Swift: initial support
This commit is contained in:
parent
8e1e6c8254
commit
85acefab95
33 changed files with 3476 additions and 1 deletions
|
@ -202,6 +202,7 @@ option(ENABLE_DEMCONVERT "Set to ON to build the dem conversion tool (default)"
|
||||||
option(ENABLE_HID_INPUT "Set to ON to build HID-based input code" OFF)
|
option(ENABLE_HID_INPUT "Set to ON to build HID-based input code" OFF)
|
||||||
option(ENABLE_PLIB_JOYSTICK "Set to ON to enable legacy joystick code (default)" ON)
|
option(ENABLE_PLIB_JOYSTICK "Set to ON to enable legacy joystick code (default)" ON)
|
||||||
option(ENABLE_COMPOSITOR "Set to ON to enable the Compositor-based Viewer" OFF)
|
option(ENABLE_COMPOSITOR "Set to ON to enable the Compositor-based Viewer" OFF)
|
||||||
|
option(ENABLE_SWIFT "Set to ON to build the swift module" OFF)
|
||||||
|
|
||||||
|
|
||||||
# Test-suite options.
|
# Test-suite options.
|
||||||
|
@ -263,6 +264,21 @@ if(EVENT_INPUT)
|
||||||
endif()
|
endif()
|
||||||
endif(EVENT_INPUT)
|
endif(EVENT_INPUT)
|
||||||
|
|
||||||
|
if (ENABLE_SWIFT)
|
||||||
|
message(STATUS "SWIFT support requested, checking for DBus/libEvent")
|
||||||
|
# DBUS
|
||||||
|
find_package(DBus REQUIRED)
|
||||||
|
list(APPEND PLATFORM_LIBS ${DBUS_LIBRARIES})
|
||||||
|
|
||||||
|
#libevent
|
||||||
|
find_package(LibEvent REQUIRED)
|
||||||
|
list(APPEND PLATFORM_LIBS ${LIBEVENT_LIB})
|
||||||
|
|
||||||
|
if (NOT DBUS_LIBRARIES OR NOT LIBEVENT_LIB)
|
||||||
|
message(FATAL_ERROR "SWIFT support requested, please ensure DBus/libEvent are available")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# check required dependencies
|
# check required dependencies
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
@ -497,7 +513,9 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
||||||
${OPENGL_INCLUDE_DIR}
|
${OPENGL_INCLUDE_DIR}
|
||||||
${SIMGEAR_INCLUDE_DIRS}
|
${SIMGEAR_INCLUDE_DIRS}
|
||||||
${PLIB_INCLUDE_DIR}
|
${PLIB_INCLUDE_DIR}
|
||||||
${SQLITE3_INCLUDED_DIR} )
|
${SQLITE3_INCLUDED_DIR}
|
||||||
|
${DBUS_INCLUDE_DIRS}
|
||||||
|
${LIBEVENT_INCLUDE_DIR} )
|
||||||
|
|
||||||
if (USE_AEONWAVE)
|
if (USE_AEONWAVE)
|
||||||
find_package(AAX REQUIRED)
|
find_package(AAX REQUIRED)
|
||||||
|
|
59
CMakeModules/FindDBus.cmake
Normal file
59
CMakeModules/FindDBus.cmake
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# - Try to find DBus
|
||||||
|
# Once done, this will define
|
||||||
|
#
|
||||||
|
# DBUS_FOUND - system has DBus
|
||||||
|
# DBUS_INCLUDE_DIRS - the DBus include directories
|
||||||
|
# DBUS_LIBRARIES - link these to use DBus
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.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.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS 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 HOLDER OR ITS
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
FIND_PACKAGE(PkgConfig)
|
||||||
|
PKG_CHECK_MODULES(PC_DBUS QUIET dbus-1)
|
||||||
|
|
||||||
|
FIND_LIBRARY(DBUS_LIBRARIES
|
||||||
|
NAMES dbus-1
|
||||||
|
HINTS ${PC_DBUS_LIBDIR}
|
||||||
|
${PC_DBUS_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_PATH(DBUS_INCLUDE_DIR
|
||||||
|
NAMES dbus/dbus.h
|
||||||
|
HINTS ${PC_DBUS_INCLUDEDIR}
|
||||||
|
${PC_DBUS_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
GET_FILENAME_COMPONENT(_DBUS_LIBRARY_DIR ${DBUS_LIBRARIES} PATH)
|
||||||
|
FIND_PATH(DBUS_ARCH_INCLUDE_DIR
|
||||||
|
NAMES dbus/dbus-arch-deps.h
|
||||||
|
HINTS ${PC_DBUS_INCLUDEDIR}
|
||||||
|
${PC_DBUS_INCLUDE_DIRS}
|
||||||
|
${_DBUS_LIBRARY_DIR}
|
||||||
|
${DBUS_INCLUDE_DIR}
|
||||||
|
PATH_SUFFIXES include
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
|
||||||
|
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DBUS REQUIRED_VARS DBUS_INCLUDE_DIRS DBUS_LIBRARIES)
|
11
CMakeModules/FindLibEvent.cmake
Normal file
11
CMakeModules/FindLibEvent.cmake
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Finding LibEvent (https://libevent.org/)
|
||||||
|
# Defining:
|
||||||
|
# LIBEVENT_LIB
|
||||||
|
# LIBEVENT_INCLUDE_DIR
|
||||||
|
|
||||||
|
find_path(LIBEVENT_INCLUDE_DIR event.h PATHS ${LibEvent_INCLUDE_PATHS})
|
||||||
|
find_library(LIBEVENT_LIB NAMES event PATHS ${LibEvent_LIB_PATHS})
|
||||||
|
|
||||||
|
if(LIBEVENT_INCLUDE_DIR AND LIBEVENT_LIB)
|
||||||
|
message(STATUS "LibEvent found.")
|
||||||
|
endif()
|
|
@ -69,3 +69,5 @@
|
||||||
#cmakedefine HAVE_QRC_TRANSLATIONS
|
#cmakedefine HAVE_QRC_TRANSLATIONS
|
||||||
|
|
||||||
#cmakedefine ENABLE_COMPOSITOR
|
#cmakedefine ENABLE_COMPOSITOR
|
||||||
|
|
||||||
|
#cmakedefine ENABLE_SWIFT
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <cstring> // strcmp()
|
#include <cstring> // strcmp()
|
||||||
|
|
||||||
#if defined(SG_WINDOWS)
|
#if defined(SG_WINDOWS)
|
||||||
|
#define _WINSOCKAPI_
|
||||||
# include <io.h> // isatty()
|
# include <io.h> // isatty()
|
||||||
# include <process.h> // _getpid()
|
# include <process.h> // _getpid()
|
||||||
# include <Windows.h>
|
# include <Windows.h>
|
||||||
|
@ -117,6 +118,9 @@
|
||||||
|
|
||||||
#include <Traffic/TrafficMgr.hxx>
|
#include <Traffic/TrafficMgr.hxx>
|
||||||
#include <MultiPlayer/multiplaymgr.hxx>
|
#include <MultiPlayer/multiplaymgr.hxx>
|
||||||
|
#if defined(ENABLE_SWIFT)
|
||||||
|
#include <Network/Swift/swift_connection.hxx>
|
||||||
|
#endif
|
||||||
#include <FDM/fdm_shell.hxx>
|
#include <FDM/fdm_shell.hxx>
|
||||||
#include <Environment/ephemeris.hxx>
|
#include <Environment/ephemeris.hxx>
|
||||||
#include <Environment/environment_mgr.hxx>
|
#include <Environment/environment_mgr.hxx>
|
||||||
|
@ -572,6 +576,12 @@ int fgInitConfig ( int argc, char **argv, bool reinit )
|
||||||
fgSetBool("/sim/developer-mode", developerMode);
|
fgSetBool("/sim/developer-mode", developerMode);
|
||||||
sglog().setDeveloperMode(developerMode);
|
sglog().setDeveloperMode(developerMode);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SWIFT
|
||||||
|
//Set standard settings for swift connection
|
||||||
|
fgSetString("/sim/swift/adress","127.0.0.1");
|
||||||
|
fgSetString("/sim/swift/port","45003");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Read global defaults from $FG_ROOT/defaults
|
// Read global defaults from $FG_ROOT/defaults
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Reading global defaults");
|
SG_LOG(SG_GENERAL, SG_INFO, "Reading global defaults");
|
||||||
SGPath defaultsXML = globals->get_fg_root() / "defaults.xml";
|
SGPath defaultsXML = globals->get_fg_root() / "defaults.xml";
|
||||||
|
@ -937,6 +947,14 @@ void fgCreateSubsystems(bool duringReset) {
|
||||||
|
|
||||||
globals->add_subsystem("mp", new FGMultiplayMgr, SGSubsystemMgr::POST_FDM);
|
globals->add_subsystem("mp", new FGMultiplayMgr, SGSubsystemMgr::POST_FDM);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SWIFT
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Initialize Swift subsystem
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
globals->add_subsystem("swift", new SwiftConnection, SGSubsystemMgr::POST_FDM);
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Initialise the AI Model Manager
|
// Initialise the AI Model Manager
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
#include <ATC/atc_mgr.hxx>
|
#include <ATC/atc_mgr.hxx>
|
||||||
#include <AIModel/AIManager.hxx>
|
#include <AIModel/AIManager.hxx>
|
||||||
#include <MultiPlayer/multiplaymgr.hxx>
|
#include <MultiPlayer/multiplaymgr.hxx>
|
||||||
|
#if defined(ENABLE_SWIFT)
|
||||||
|
# include <Network/Swift/swift_connection.hxx>
|
||||||
|
#endif
|
||||||
#include <AIModel/submodel.hxx>
|
#include <AIModel/submodel.hxx>
|
||||||
#include <Aircraft/controls.hxx>
|
#include <Aircraft/controls.hxx>
|
||||||
#include <Input/input.hxx>
|
#include <Input/input.hxx>
|
||||||
|
@ -107,6 +110,9 @@ SGSubsystem* createSubsystemByName(const std::string& name)
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_IAX
|
#ifdef ENABLE_IAX
|
||||||
MAKE_SUB(FGCom, "fgcom");
|
MAKE_SUB(FGCom, "fgcom");
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_SWIFT
|
||||||
|
MAKE_SUB(SwiftConnection, "swift");
|
||||||
#endif
|
#endif
|
||||||
MAKE_SUB(FGLight, "lighting");
|
MAKE_SUB(FGLight, "lighting");
|
||||||
MAKE_SUB(FGAircraftModel, "aircraft-model");
|
MAKE_SUB(FGAircraftModel, "aircraft-model");
|
||||||
|
|
|
@ -73,3 +73,6 @@ endif()
|
||||||
|
|
||||||
add_subdirectory(http)
|
add_subdirectory(http)
|
||||||
|
|
||||||
|
if(ENABLE_SWIFT)
|
||||||
|
add_subdirectory(Swift)
|
||||||
|
endif()
|
34
src/Network/Swift/CMakeLists.txt
Normal file
34
src/Network/Swift/CMakeLists.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
include(FlightGearComponent)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
swift_connection.cxx
|
||||||
|
dbusconnection.cpp
|
||||||
|
dbusobject.cpp
|
||||||
|
dbusmessage.cpp
|
||||||
|
dbusdispatcher.cpp
|
||||||
|
dbuserror.cpp
|
||||||
|
dbusserver.cpp
|
||||||
|
plugin.cpp
|
||||||
|
service.cpp
|
||||||
|
traffic.cpp
|
||||||
|
swiftaircraft.cpp
|
||||||
|
SwiftAircraftManager.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
swift_connection.hxx
|
||||||
|
dbusconnection.h
|
||||||
|
dbusobject.h
|
||||||
|
dbusmessage.h
|
||||||
|
dbuscallbacks.h
|
||||||
|
dbusdispatcher.h
|
||||||
|
dbuserror.h
|
||||||
|
dbusserver.h
|
||||||
|
plugin.h
|
||||||
|
service.h
|
||||||
|
traffic.h
|
||||||
|
swiftaircraft.h
|
||||||
|
SwiftAircraftManager.h
|
||||||
|
)
|
||||||
|
|
||||||
|
flightgear_component(Swift "${SOURCES}" "${HEADERS}")
|
102
src/Network/Swift/SwiftAircraft.cpp
Normal file
102
src/Network/Swift/SwiftAircraft.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// SwiftAircraft.cpp - Class representing an aircraft generated by swift
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <osgDB/FileUtils>
|
||||||
|
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/scene/model/modellib.hxx>
|
||||||
|
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||||
|
|
||||||
|
#include "SwiftAircraft.h"
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <Main/globals.hxx>
|
||||||
|
#include <Scenery/scenery.hxx>
|
||||||
|
#include <Scripting/NasalModelData.hxx>
|
||||||
|
#include <Scripting/NasalSys.hxx>
|
||||||
|
#include <Sound/fg_fx.hxx>
|
||||||
|
|
||||||
|
FGSwiftAircraft::FGSwiftAircraft(std::string callsign, std::string modelpath)
|
||||||
|
{
|
||||||
|
using namespace simgear;
|
||||||
|
_model = SGModelLib::loadModel(modelpath);
|
||||||
|
_model->setName(callsign);
|
||||||
|
if (_model.valid()) {
|
||||||
|
aip.init(_model);
|
||||||
|
aip.setVisible(true);
|
||||||
|
aip.update();
|
||||||
|
globals->get_scenery()->get_models_branch()->addChild(aip.getSceneGraph());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FGSwiftAircraft::updatePosition(SGGeod newPosition, SGVec3d orientation)
|
||||||
|
{
|
||||||
|
|
||||||
|
position = newPosition;
|
||||||
|
aip.setPosition(position);
|
||||||
|
aip.setPitchDeg(orientation.x());
|
||||||
|
aip.setRollDeg(orientation.y());
|
||||||
|
aip.setHeadingDeg(orientation.z());
|
||||||
|
aip.update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FGSwiftAircraft::~FGSwiftAircraft()
|
||||||
|
{
|
||||||
|
aip.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FGSwiftAircraft::getLatDeg()
|
||||||
|
{
|
||||||
|
return position.getLatitudeDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
double FGSwiftAircraft::getLongDeg()
|
||||||
|
{
|
||||||
|
return position.getLongitudeDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
double FGSwiftAircraft::getFudgeFactor()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool FGSwiftAircraft::operator<(std::string extCallsign)
|
||||||
|
{
|
||||||
|
return _model->getName().compare(extCallsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FGSwiftAircraft::getGroundElevation()
|
||||||
|
{
|
||||||
|
double alt;
|
||||||
|
globals->get_scenery()->get_elevation_m(position,alt,0);
|
||||||
|
return alt;
|
||||||
|
|
||||||
|
}
|
59
src/Network/Swift/SwiftAircraft.h
Normal file
59
src/Network/Swift/SwiftAircraft.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// SwiftAircraft.h - Class representing an aircraft generated by swift
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef FGSWIFTAIRCRAFT_H
|
||||||
|
#define FGSWIFTAIRCRAFT_H
|
||||||
|
#pragma once
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <simgear/constants.h>
|
||||||
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
#include <simgear/props/tiedpropertylist.hxx>
|
||||||
|
#include <simgear/scene/model/placement.hxx>
|
||||||
|
#include <simgear/sg_inlines.h>
|
||||||
|
#include <simgear/structure/SGReferenced.hxx>
|
||||||
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
|
|
||||||
|
namespace osg {
|
||||||
|
class PagedLOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FGSwiftAircraft
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGSwiftAircraft(std::string callsign, std::string modelpath);
|
||||||
|
bool updatePosition(SGGeod newPosition, SGVec3d orientation);
|
||||||
|
~FGSwiftAircraft();
|
||||||
|
std::string getName() { return _model->getName(); };
|
||||||
|
double getLatDeg();
|
||||||
|
double getLongDeg();
|
||||||
|
double getGroundElevation();
|
||||||
|
double getFudgeFactor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SGGeod position;
|
||||||
|
osg::ref_ptr<osg::Node> _model;
|
||||||
|
SGModelPlacement aip;
|
||||||
|
inline bool operator<(std::string extCallsign);
|
||||||
|
};
|
||||||
|
#endif
|
94
src/Network/Swift/SwiftAircraftManager.cpp
Normal file
94
src/Network/Swift/SwiftAircraftManager.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
// SwiftAircraftManager.cpp - Manager class for aircrafts generated by swift
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "SwiftAircraftManager.h"
|
||||||
|
#include "SwiftAircraft.h"
|
||||||
|
|
||||||
|
FGSwiftAircraftManager::FGSwiftAircraftManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FGSwiftAircraftManager::~FGSwiftAircraftManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FGSwiftAircraftManager::addPlane(std::string callsign, std::string modelString)
|
||||||
|
{
|
||||||
|
if (aircraftByCallsign.find(callsign) != aircraftByCallsign.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FGSwiftAircraft* curAircraft = new FGSwiftAircraft(callsign, modelString);
|
||||||
|
aircraftByCallsign.insert(std::pair<std::string, FGSwiftAircraft*>(callsign, curAircraft));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGSwiftAircraftManager::updatePlanes(std::vector<std::string> callsigns, std::vector<SGGeod> positions, std::vector<SGVec3d> orientations, std::vector<bool> onGrounds)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < callsigns.size(); i++) {
|
||||||
|
auto it = aircraftByCallsign.find(callsigns.at(i));
|
||||||
|
if (it != aircraftByCallsign.end()) {
|
||||||
|
it->second->updatePosition(positions.at(i), orientations.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGSwiftAircraftManager::getRemoteAircraftData(std::vector<std::string>& callsigns, std::vector<double>& latitudesDeg, std::vector<double>& longitudesDeg, std::vector<double>& elevationsM, std::vector<double>& verticalOffsets) const
|
||||||
|
{
|
||||||
|
const auto requestedCallsigns = callsigns;
|
||||||
|
callsigns.clear();
|
||||||
|
latitudesDeg.clear();
|
||||||
|
longitudesDeg.clear();
|
||||||
|
elevationsM.clear();
|
||||||
|
verticalOffsets.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < requestedCallsigns.size(); i++) {
|
||||||
|
auto it = aircraftByCallsign.find(requestedCallsigns.at(i));
|
||||||
|
if (it != aircraftByCallsign.end()) {
|
||||||
|
double latDeg = it->second->getLatDeg();
|
||||||
|
double lonDeg = it->second->getLongDeg();
|
||||||
|
double groundElevation = it->second->getGroundElevation();
|
||||||
|
double fudgeFactor = it->second->getFudgeFactor();
|
||||||
|
|
||||||
|
callsigns.push_back(requestedCallsigns.at(i));
|
||||||
|
latitudesDeg.push_back(latDeg);
|
||||||
|
longitudesDeg.push_back(lonDeg);
|
||||||
|
elevationsM.push_back(groundElevation);
|
||||||
|
verticalOffsets.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGSwiftAircraftManager::removePlane(std::string callsign)
|
||||||
|
{
|
||||||
|
auto it = aircraftByCallsign.find(callsign);
|
||||||
|
if (it != aircraftByCallsign.end()) {
|
||||||
|
delete it->second;
|
||||||
|
aircraftByCallsign.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGSwiftAircraftManager::removeAllPlanes()
|
||||||
|
{
|
||||||
|
for (auto it = aircraftByCallsign.begin(); it != aircraftByCallsign.end(); ++it) {
|
||||||
|
delete it->second;
|
||||||
|
aircraftByCallsign.erase(it);
|
||||||
|
}
|
||||||
|
}
|
39
src/Network/Swift/SwiftAircraftManager.h
Normal file
39
src/Network/Swift/SwiftAircraftManager.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// SwiftAircraftManager.h - Manger class for aircrafts generated for swift
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "SwiftAircraft.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef FGSWIFTAIRCRAFTMANAGER_H
|
||||||
|
#define FGSWIFTAIRCRAFTMANAGER_H
|
||||||
|
|
||||||
|
class FGSwiftAircraftManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGSwiftAircraftManager();
|
||||||
|
~FGSwiftAircraftManager();
|
||||||
|
std::map<std::string, FGSwiftAircraft*> aircraftByCallsign;
|
||||||
|
bool addPlane(std::string callsign, std::string modelString);
|
||||||
|
void updatePlanes(std::vector<std::string> callsigns, std::vector<SGGeod> positions, std::vector<SGVec3d> orientations, std::vector<bool> onGrounds);
|
||||||
|
void getRemoteAircraftData(std::vector<std::string>& callsigns, std::vector<double>& latitudesDeg, std::vector<double>& longitudesDeg,
|
||||||
|
std::vector<double>& elevationsM, std::vector<double>& verticalOffsets) const;
|
||||||
|
void removePlane(std::string callsign);
|
||||||
|
void removeAllPlanes();
|
||||||
|
};
|
||||||
|
#endif
|
64
src/Network/Swift/dbuscallbacks.h
Normal file
64
src/Network/Swift/dbuscallbacks.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// dbuscallbacks.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSASYNCCALLBACKS_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSASYNCCALLBACKS_H
|
||||||
|
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
//! \cond PRIVATE
|
||||||
|
template <typename T>
|
||||||
|
class DBusAsyncCallbacks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DBusAsyncCallbacks() = default;
|
||||||
|
DBusAsyncCallbacks(const std::function<dbus_bool_t(T *)> &add,
|
||||||
|
const std::function<void(T *)> &remove,
|
||||||
|
const std::function<void(T *)> &toggled)
|
||||||
|
: m_addHandler(add), m_removeHandler(remove), m_toggledHandler(toggled)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
static dbus_bool_t add(T *watch, void *refcon)
|
||||||
|
{
|
||||||
|
return static_cast<DBusAsyncCallbacks *>(refcon)->m_addHandler(watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove(T *watch, void *refcon)
|
||||||
|
{
|
||||||
|
return static_cast<DBusAsyncCallbacks *>(refcon)->m_removeHandler(watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toggled(T *watch, void *refcon)
|
||||||
|
{
|
||||||
|
return static_cast<DBusAsyncCallbacks *>(refcon)->m_toggledHandler(watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<dbus_bool_t(T *)> m_addHandler;
|
||||||
|
std::function<void(T *)> m_removeHandler;
|
||||||
|
std::function<void(T *)> m_toggledHandler;
|
||||||
|
};
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
195
src/Network/Swift/dbusconnection.cpp
Normal file
195
src/Network/Swift/dbusconnection.cpp
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// dbusconnection.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbusconnection.h"
|
||||||
|
#include "dbusobject.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
CDBusConnection::CDBusConnection()
|
||||||
|
{
|
||||||
|
dbus_threads_init_default();
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusConnection::CDBusConnection(DBusConnection *connection)
|
||||||
|
{
|
||||||
|
m_connection.reset(connection);
|
||||||
|
dbus_connection_ref(connection);
|
||||||
|
// Don't exit application, if the connection is disconnected
|
||||||
|
dbus_connection_set_exit_on_disconnect(connection, false);
|
||||||
|
dbus_connection_add_filter(connection, filterDisconnectedFunction, this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusConnection::~CDBusConnection()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
if (m_connection) { dispatch(); } // dispatch is virtual, but safe to call in dtor, as it's declared final
|
||||||
|
if (m_dispatcher) { m_dispatcher->remove(this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusConnection::connect(BusType type)
|
||||||
|
{
|
||||||
|
assert(type == SessionBus);
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
|
||||||
|
DBusBusType dbusBusType;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SessionBus: dbusBusType = DBUS_BUS_SESSION; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_connection.reset(dbus_bus_get_private(dbusBusType, &error));
|
||||||
|
if (dbus_error_is_set(&error))
|
||||||
|
{
|
||||||
|
m_lastError = CDBusError(&error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't exit application, if the connection is disconnected
|
||||||
|
dbus_connection_set_exit_on_disconnect(m_connection.get(), false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::setDispatcher(CDBusDispatcher *dispatcher)
|
||||||
|
{
|
||||||
|
assert(dispatcher);
|
||||||
|
|
||||||
|
m_dispatcher = dispatcher;
|
||||||
|
|
||||||
|
m_dispatcher->add(this);
|
||||||
|
|
||||||
|
dbus_connection_set_watch_functions(
|
||||||
|
m_connection.get(),
|
||||||
|
dispatcher->m_watchCallbacks.add,
|
||||||
|
dispatcher->m_watchCallbacks.remove,
|
||||||
|
dispatcher->m_watchCallbacks.toggled,
|
||||||
|
&dispatcher->m_watchCallbacks, nullptr);
|
||||||
|
|
||||||
|
dbus_connection_set_timeout_functions(
|
||||||
|
m_connection.get(),
|
||||||
|
dispatcher->m_timeoutCallbacks.add,
|
||||||
|
dispatcher->m_timeoutCallbacks.remove,
|
||||||
|
dispatcher->m_timeoutCallbacks.toggled,
|
||||||
|
&dispatcher->m_timeoutCallbacks, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::requestName(const std::string &name)
|
||||||
|
{
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
dbus_bus_request_name(m_connection.get(), name.c_str(), 0, &error);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusConnection::isConnected() const
|
||||||
|
{
|
||||||
|
return m_connection && dbus_connection_get_is_connected(m_connection.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::registerDisconnectedCallback(CDBusObject *obj, DisconnectedCallback func)
|
||||||
|
{
|
||||||
|
m_disconnectedCallbacks[obj] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::unregisterDisconnectedCallback(CDBusObject *obj)
|
||||||
|
{
|
||||||
|
auto it = m_disconnectedCallbacks.find(obj);
|
||||||
|
if (it == m_disconnectedCallbacks.end()) { return; }
|
||||||
|
m_disconnectedCallbacks.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::registerObjectPath(CDBusObject *object, const std::string &interfaceName, const std::string &objectPath, const DBusObjectPathVTable &dbusObjectPathVTable)
|
||||||
|
{
|
||||||
|
(void) interfaceName;
|
||||||
|
if (!m_connection) { return; }
|
||||||
|
|
||||||
|
dbus_connection_try_register_object_path(m_connection.get(), objectPath.c_str(), &dbusObjectPathVTable, object, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::sendMessage(const CDBusMessage &message)
|
||||||
|
{
|
||||||
|
if (!isConnected()) { return; }
|
||||||
|
dbus_uint32_t serial = message.getSerial();
|
||||||
|
dbus_connection_send(m_connection.get(), message.m_message, &serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::close()
|
||||||
|
{
|
||||||
|
if (m_connection) { dbus_connection_close(m_connection.get()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::dispatch()
|
||||||
|
{
|
||||||
|
dbus_connection_ref(m_connection.get());
|
||||||
|
if (dbus_connection_get_dispatch_status(m_connection.get()) == DBUS_DISPATCH_DATA_REMAINS)
|
||||||
|
{
|
||||||
|
while (dbus_connection_dispatch(m_connection.get()) == DBUS_DISPATCH_DATA_REMAINS);
|
||||||
|
}
|
||||||
|
dbus_connection_unref(m_connection.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status)
|
||||||
|
{
|
||||||
|
if (dbus_connection_get_is_connected(connection) == FALSE) { return; }
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case DBUS_DISPATCH_DATA_REMAINS:
|
||||||
|
//m_dispatcher->add(this);
|
||||||
|
break;
|
||||||
|
case DBUS_DISPATCH_COMPLETE:
|
||||||
|
case DBUS_DISPATCH_NEED_MEMORY:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusConnection::setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status, void *data)
|
||||||
|
{
|
||||||
|
auto *obj = static_cast<CDBusConnection *>(data);
|
||||||
|
obj->setDispatchStatus(connection, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusHandlerResult CDBusConnection::filterDisconnectedFunction(DBusConnection *connection, DBusMessage *message, void *data)
|
||||||
|
{
|
||||||
|
(void)connection; // unused
|
||||||
|
|
||||||
|
auto *obj = static_cast<CDBusConnection *>(data);
|
||||||
|
|
||||||
|
DBusError err;
|
||||||
|
dbus_error_init(&err);
|
||||||
|
|
||||||
|
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
|
||||||
|
{
|
||||||
|
for (auto it = obj->m_disconnectedCallbacks.begin(); it != obj->m_disconnectedCallbacks.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second();
|
||||||
|
}
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
119
src/Network/Swift/dbusconnection.h
Normal file
119
src/Network/Swift/dbusconnection.h
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
// dbusconnection.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSCONNECTION_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSCONNECTION_H
|
||||||
|
|
||||||
|
#include "dbusmessage.h"
|
||||||
|
#include "dbuserror.h"
|
||||||
|
#include "dbuscallbacks.h"
|
||||||
|
#include "dbusdispatcher.h"
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDBusObject;
|
||||||
|
|
||||||
|
//! DBus connection
|
||||||
|
class CDBusConnection : public IDispatchable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Bus type
|
||||||
|
enum BusType { SessionBus };
|
||||||
|
|
||||||
|
//! Disconnect Callback
|
||||||
|
using DisconnectedCallback = std::function<void()>;
|
||||||
|
|
||||||
|
//! Default constructor
|
||||||
|
CDBusConnection();
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
CDBusConnection(DBusConnection *connection);
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~CDBusConnection() override;
|
||||||
|
|
||||||
|
// The ones below are not implemented yet.
|
||||||
|
// If you need them, make sure that connection reference count is correct
|
||||||
|
CDBusConnection(const CDBusConnection &) = delete;
|
||||||
|
CDBusConnection &operator=(const CDBusConnection &) = delete;
|
||||||
|
|
||||||
|
//! Connect to bus
|
||||||
|
bool connect(BusType type);
|
||||||
|
|
||||||
|
//! Set dispatcher
|
||||||
|
void setDispatcher(CDBusDispatcher *dispatcher);
|
||||||
|
|
||||||
|
//! Request name to the bus
|
||||||
|
void requestName(const std::string &name);
|
||||||
|
|
||||||
|
//! Is connected?
|
||||||
|
bool isConnected() const;
|
||||||
|
|
||||||
|
//! Register a disconnected callback
|
||||||
|
void registerDisconnectedCallback(CDBusObject *obj, DisconnectedCallback func);
|
||||||
|
|
||||||
|
//! Register a disconnected callback
|
||||||
|
void unregisterDisconnectedCallback(CDBusObject *obj);
|
||||||
|
|
||||||
|
//! Register DBus object with interfaceName and objectPath.
|
||||||
|
//! \param object
|
||||||
|
//! \param interfaceName
|
||||||
|
//! \param objectPath
|
||||||
|
//! \param dbusObjectPathVTable Virtual table handling DBus messages
|
||||||
|
void registerObjectPath(CDBusObject *object, const std::string &interfaceName, const std::string &objectPath, const DBusObjectPathVTable &dbusObjectPathVTable);
|
||||||
|
|
||||||
|
//! Send message to bus
|
||||||
|
void sendMessage(const CDBusMessage &message);
|
||||||
|
|
||||||
|
//! Close connection
|
||||||
|
void close();
|
||||||
|
|
||||||
|
//! Get the last error
|
||||||
|
CDBusError lastError() const { return m_lastError; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// cppcheck-suppress virtualCallInConstructor
|
||||||
|
virtual void dispatch() override final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status);
|
||||||
|
static void setDispatchStatus(DBusConnection *connection, DBusDispatchStatus status, void *data);
|
||||||
|
static DBusHandlerResult filterDisconnectedFunction(DBusConnection *connection, DBusMessage *message, void *data);
|
||||||
|
|
||||||
|
struct DBusConnectionDeleter
|
||||||
|
{
|
||||||
|
void operator()(DBusConnection *obj) const { dbus_connection_unref(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
CDBusDispatcher *m_dispatcher = nullptr;
|
||||||
|
std::unique_ptr<DBusConnection, DBusConnectionDeleter> m_connection;
|
||||||
|
CDBusError m_lastError;
|
||||||
|
std::unordered_map<CDBusObject *, DisconnectedCallback> m_disconnectedCallbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
245
src/Network/Swift/dbusdispatcher.cpp
Normal file
245
src/Network/Swift/dbusdispatcher.cpp
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
// dbus-dispatcher.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbusdispatcher.h"
|
||||||
|
#include "dbusconnection.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Functor struct deleteing an event
|
||||||
|
struct EventDeleter
|
||||||
|
{
|
||||||
|
//! Delete functor
|
||||||
|
void operator()(event *obj) const
|
||||||
|
{
|
||||||
|
event_del(obj);
|
||||||
|
event_free(obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! DBus watch handler
|
||||||
|
class WatchHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
WatchHandler(event_base *base, DBusWatch *watch)
|
||||||
|
: m_base(base), m_watch(watch)
|
||||||
|
{
|
||||||
|
const unsigned int flags = dbus_watch_get_flags(watch);
|
||||||
|
short monitoredEvents = EV_PERSIST;
|
||||||
|
|
||||||
|
if (flags & DBUS_WATCH_READABLE) { monitoredEvents |= EV_READ; }
|
||||||
|
if (flags & DBUS_WATCH_WRITABLE) { monitoredEvents |= EV_WRITE; }
|
||||||
|
|
||||||
|
const int fd = dbus_watch_get_unix_fd(watch);
|
||||||
|
m_event.reset(event_new(m_base, fd, monitoredEvents, callback, this));
|
||||||
|
event_add(m_event.get(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get DBus watch
|
||||||
|
DBusWatch *getWatch() { return m_watch; }
|
||||||
|
|
||||||
|
//! Get DBus watch
|
||||||
|
const DBusWatch *getWatch() const { return m_watch; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Event callback
|
||||||
|
static void callback(evutil_socket_t fd, short event, void *data)
|
||||||
|
{
|
||||||
|
(void) fd; // Not really unused, but GCC/Clang still complain about it.
|
||||||
|
auto *watchHandler = static_cast<WatchHandler *>(data);
|
||||||
|
|
||||||
|
unsigned int flags = 0;
|
||||||
|
if (event & EV_READ) { flags |= DBUS_WATCH_READABLE; }
|
||||||
|
if (event & EV_WRITE) { flags |= DBUS_WATCH_WRITABLE; }
|
||||||
|
dbus_watch_handle(watchHandler->m_watch, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_base *m_base = nullptr;
|
||||||
|
std::unique_ptr<event, EventDeleter> m_event;
|
||||||
|
DBusWatch *m_watch = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! DBus timeout handler
|
||||||
|
class TimeoutHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
TimeoutHandler(event_base *base, DBusTimeout *timeout)
|
||||||
|
: m_base(base), m_timeout(timeout)
|
||||||
|
{
|
||||||
|
timeval timer;
|
||||||
|
const int interval = dbus_timeout_get_interval(timeout);
|
||||||
|
timer.tv_sec = interval / 1000;
|
||||||
|
timer.tv_usec = (interval % 1000) * 1000;
|
||||||
|
|
||||||
|
m_event.reset(evtimer_new(m_base, callback, this));
|
||||||
|
evtimer_add(m_event.get(), &timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Get DBus timeout
|
||||||
|
const DBusTimeout *getTimeout() const { return m_timeout; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Event callback
|
||||||
|
static void callback(evutil_socket_t fd, short event, void *data)
|
||||||
|
{
|
||||||
|
(void) fd; // unused
|
||||||
|
(void) event; // unused
|
||||||
|
auto *timeoutHandler = static_cast<TimeoutHandler *>(data);
|
||||||
|
dbus_timeout_handle(timeoutHandler->m_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_base *m_base = nullptr;
|
||||||
|
std::unique_ptr<event, EventDeleter> m_event;
|
||||||
|
DBusTimeout *m_timeout = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Generic Timer
|
||||||
|
class Timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Timer() = default;
|
||||||
|
//! Constructor
|
||||||
|
Timer(event_base *base, const timeval &timeout, const std::function<void()> &func)
|
||||||
|
: m_base(base), m_func(func)
|
||||||
|
{
|
||||||
|
m_event.reset(evtimer_new(m_base, callback, this));
|
||||||
|
evtimer_add(m_event.get(), &timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Event callback
|
||||||
|
static void callback(evutil_socket_t fd, short event, void *data)
|
||||||
|
{
|
||||||
|
(void) fd; // unused
|
||||||
|
(void) event; // unused
|
||||||
|
auto *timer = static_cast<Timer *>(data);
|
||||||
|
timer->m_func();
|
||||||
|
delete timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_base *m_base = nullptr;
|
||||||
|
std::unique_ptr<event, EventDeleter> m_event;
|
||||||
|
std::function<void()> m_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
CDBusDispatcher::CDBusDispatcher() :
|
||||||
|
m_eventBase(event_base_new())
|
||||||
|
{
|
||||||
|
using namespace std::placeholders;
|
||||||
|
m_watchCallbacks = WatchCallbacks(std::bind(&CDBusDispatcher::dbusAddWatch, this, _1),
|
||||||
|
std::bind(&CDBusDispatcher::dbusRemoveWatch, this, _1),
|
||||||
|
std::bind(&CDBusDispatcher::dbusWatchToggled, this, _1));
|
||||||
|
|
||||||
|
m_timeoutCallbacks = TimeoutCallbacks(std::bind(&CDBusDispatcher::dbusAddTimeout, this, _1),
|
||||||
|
std::bind(&CDBusDispatcher::dbusRemoveTimeout, this, _1),
|
||||||
|
std::bind(&CDBusDispatcher::dbusTimeoutToggled, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusDispatcher::~CDBusDispatcher()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::add(IDispatchable *dispatchable)
|
||||||
|
{
|
||||||
|
m_dispatchList.push_back(dispatchable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::remove(IDispatchable *dispatchable)
|
||||||
|
{
|
||||||
|
auto it = std::find(m_dispatchList.begin(), m_dispatchList.end(), dispatchable);
|
||||||
|
if (it != m_dispatchList.end()) { m_dispatchList.erase(it); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::waitAndRun()
|
||||||
|
{
|
||||||
|
if (!m_eventBase) { return; }
|
||||||
|
event_base_dispatch(m_eventBase.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::runOnce()
|
||||||
|
{
|
||||||
|
if (!m_eventBase) { return; }
|
||||||
|
event_base_loop(m_eventBase.get(), EVLOOP_NONBLOCK);
|
||||||
|
dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::dispatch()
|
||||||
|
{
|
||||||
|
if (m_dispatchList.empty()) { return; }
|
||||||
|
|
||||||
|
for (IDispatchable *dispatchable : m_dispatchList)
|
||||||
|
{
|
||||||
|
dispatchable->dispatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_bool_t CDBusDispatcher::dbusAddWatch(DBusWatch *watch)
|
||||||
|
{
|
||||||
|
if (dbus_watch_get_enabled(watch) == FALSE) { return true; }
|
||||||
|
|
||||||
|
int fd = dbus_watch_get_unix_fd(watch);
|
||||||
|
m_watchers.emplace(fd, new WatchHandler(m_eventBase.get(), watch));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::dbusRemoveWatch(DBusWatch *watch)
|
||||||
|
{
|
||||||
|
for (auto it = m_watchers.begin(); it != m_watchers.end();)
|
||||||
|
{
|
||||||
|
if (it->second->getWatch() == watch) { it = m_watchers.erase(it); }
|
||||||
|
else { ++it; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::dbusWatchToggled(DBusWatch *watch)
|
||||||
|
{
|
||||||
|
if (dbus_watch_get_enabled(watch) == TRUE) { dbusAddWatch(watch); }
|
||||||
|
else { dbusRemoveWatch(watch); }
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_bool_t CDBusDispatcher::dbusAddTimeout(DBusTimeout *timeout)
|
||||||
|
{
|
||||||
|
if (dbus_timeout_get_enabled(timeout) == FALSE) { return TRUE; }
|
||||||
|
m_timeouts.emplace_back(new TimeoutHandler(m_eventBase.get(), timeout));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::dbusRemoveTimeout(DBusTimeout *timeout)
|
||||||
|
{
|
||||||
|
auto predicate = [timeout](const std::unique_ptr<TimeoutHandler> &ptr)
|
||||||
|
{
|
||||||
|
return ptr->getTimeout() == timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
m_timeouts.erase(std::remove_if(m_timeouts.begin(), m_timeouts.end(), predicate), m_timeouts.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusDispatcher::dbusTimeoutToggled(DBusTimeout *timeout)
|
||||||
|
{
|
||||||
|
if (dbus_timeout_get_enabled(timeout) == TRUE)
|
||||||
|
dbusAddTimeout(timeout);
|
||||||
|
else
|
||||||
|
dbusRemoveTimeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
114
src/Network/Swift/dbusdispatcher.h
Normal file
114
src/Network/Swift/dbusdispatcher.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// dbusdispatcher.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSDISPATCHER_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSDISPATCHER_H
|
||||||
|
|
||||||
|
#include "dbuscallbacks.h"
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
class WatchHandler;
|
||||||
|
class TimeoutHandler;
|
||||||
|
class CDBusConnection;
|
||||||
|
class CDBusDispatcher;
|
||||||
|
|
||||||
|
//! Dispatchable Interface
|
||||||
|
class IDispatchable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Default constructor
|
||||||
|
IDispatchable() = default;
|
||||||
|
|
||||||
|
//! Default destructor
|
||||||
|
virtual ~IDispatchable() = default;
|
||||||
|
|
||||||
|
//! Dispatch execution method
|
||||||
|
virtual void dispatch() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend CDBusDispatcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! DBus Dispatcher
|
||||||
|
class CDBusDispatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CDBusDispatcher();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
virtual ~CDBusDispatcher();
|
||||||
|
|
||||||
|
//! Add dispatchable object
|
||||||
|
void add(IDispatchable *dispatchable);
|
||||||
|
|
||||||
|
//! Remove dispatchable object
|
||||||
|
void remove(IDispatchable *dispatchable);
|
||||||
|
|
||||||
|
//! Waits for events to be dispatched and handles them
|
||||||
|
void waitAndRun();
|
||||||
|
|
||||||
|
//! Dispatches ready handlers and returns without waiting
|
||||||
|
void runOnce();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class WatchHandler;
|
||||||
|
friend class TimeoutHandler;
|
||||||
|
friend class Timer;
|
||||||
|
friend class CDBusConnection;
|
||||||
|
friend class CDBusServer;
|
||||||
|
|
||||||
|
struct EventBaseDeleter
|
||||||
|
{
|
||||||
|
void operator()(event_base *obj) const { event_base_free(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using WatchCallbacks = DBusAsyncCallbacks<DBusWatch>;
|
||||||
|
using TimeoutCallbacks = DBusAsyncCallbacks<DBusTimeout>;
|
||||||
|
|
||||||
|
void dispatch();
|
||||||
|
|
||||||
|
dbus_bool_t dbusAddWatch(DBusWatch *watch);
|
||||||
|
void dbusRemoveWatch(DBusWatch *watch);
|
||||||
|
void dbusWatchToggled(DBusWatch *watch);
|
||||||
|
|
||||||
|
dbus_bool_t dbusAddTimeout(DBusTimeout *timeout);
|
||||||
|
void dbusRemoveTimeout(DBusTimeout *timeout);
|
||||||
|
void dbusTimeoutToggled(DBusTimeout *timeout);
|
||||||
|
|
||||||
|
WatchCallbacks m_watchCallbacks;
|
||||||
|
TimeoutCallbacks m_timeoutCallbacks;
|
||||||
|
std::unordered_multimap<evutil_socket_t, std::unique_ptr<WatchHandler>> m_watchers;
|
||||||
|
std::vector<std::unique_ptr<TimeoutHandler>> m_timeouts;
|
||||||
|
std::unique_ptr<event_base, EventBaseDeleter> m_eventBase;
|
||||||
|
|
||||||
|
std::vector<IDispatchable*> m_dispatchList;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
29
src/Network/Swift/dbuserror.cpp
Normal file
29
src/Network/Swift/dbuserror.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// dbuserror.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbuserror.h"
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
CDBusError::CDBusError(const DBusError *error)
|
||||||
|
: m_name(error->name), m_message(error->message)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
}
|
57
src/Network/Swift/dbuserror.h
Normal file
57
src/Network/Swift/dbuserror.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// dbuserror.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSERROR_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSERROR_H
|
||||||
|
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
//! DBus error
|
||||||
|
class CDBusError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Error type
|
||||||
|
enum ErrorType
|
||||||
|
{
|
||||||
|
NoError,
|
||||||
|
Other
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Default constructur
|
||||||
|
CDBusError() = default;
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
explicit CDBusError(const DBusError *error);
|
||||||
|
|
||||||
|
//! Get error type
|
||||||
|
ErrorType getType() const { return m_errorType; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ErrorType m_errorType = NoError;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
263
src/Network/Swift/dbusmessage.cpp
Normal file
263
src/Network/Swift/dbusmessage.cpp
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
// dbusmessage.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbusmessage.h"
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
CDBusMessage::CDBusMessage(DBusMessage *message)
|
||||||
|
{
|
||||||
|
m_message = dbus_message_ref(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage::CDBusMessage(const CDBusMessage &other)
|
||||||
|
{
|
||||||
|
m_message = dbus_message_ref(other.m_message);
|
||||||
|
m_serial = other.m_serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage::CDBusMessage(DBusMessage *message, dbus_uint32_t serial)
|
||||||
|
{
|
||||||
|
m_message = dbus_message_ref(message);
|
||||||
|
m_serial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage::~CDBusMessage()
|
||||||
|
{
|
||||||
|
dbus_message_unref(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage &CDBusMessage::operator =(CDBusMessage other)
|
||||||
|
{
|
||||||
|
std::swap(m_serial, other.m_serial);
|
||||||
|
m_message = dbus_message_ref(other.m_message);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusMessage::isMethodCall() const
|
||||||
|
{
|
||||||
|
return dbus_message_get_type(m_message) == DBUS_MESSAGE_TYPE_METHOD_CALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusMessage::wantsReply() const
|
||||||
|
{
|
||||||
|
return !dbus_message_get_no_reply(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CDBusMessage::getSender() const
|
||||||
|
{
|
||||||
|
const char *sender = dbus_message_get_sender(m_message);
|
||||||
|
return sender ? std::string(sender) : std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_uint32_t CDBusMessage::getSerial() const
|
||||||
|
{
|
||||||
|
return dbus_message_get_serial(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CDBusMessage::getInterfaceName() const
|
||||||
|
{
|
||||||
|
return dbus_message_get_interface(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CDBusMessage::getObjectPath() const
|
||||||
|
{
|
||||||
|
return dbus_message_get_path(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CDBusMessage::getMethodName() const
|
||||||
|
{
|
||||||
|
return dbus_message_get_member(m_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::beginArgumentWrite()
|
||||||
|
{
|
||||||
|
dbus_message_iter_init_append(m_message, &m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(bool value)
|
||||||
|
{
|
||||||
|
dbus_bool_t boolean = value ? 1 : 0;
|
||||||
|
dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_BOOLEAN, &boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(const char *value)
|
||||||
|
{
|
||||||
|
dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_STRING, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(const std::string &value)
|
||||||
|
{
|
||||||
|
const char *ptr = value.c_str();
|
||||||
|
dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_STRING, &ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(int value)
|
||||||
|
{
|
||||||
|
dbus_int32_t i = value;
|
||||||
|
dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_INT32, &i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(double value)
|
||||||
|
{
|
||||||
|
dbus_message_iter_append_basic(&m_messageIterator, DBUS_TYPE_DOUBLE, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(const std::vector<double> &array)
|
||||||
|
{
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_open_container(&m_messageIterator, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE_AS_STRING, &arrayIterator);
|
||||||
|
const double *ptr = array.data();
|
||||||
|
dbus_message_iter_append_fixed_array(&arrayIterator, DBUS_TYPE_DOUBLE, &ptr, static_cast<int>(array.size()));
|
||||||
|
dbus_message_iter_close_container(&m_messageIterator, &arrayIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::appendArgument(const std::vector<std::string> &array)
|
||||||
|
{
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_open_container(&m_messageIterator, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &arrayIterator);
|
||||||
|
for (const auto &i : array)
|
||||||
|
{
|
||||||
|
const char *ptr = i.c_str();
|
||||||
|
dbus_message_iter_append_basic(&arrayIterator, DBUS_TYPE_STRING, &ptr);
|
||||||
|
}
|
||||||
|
dbus_message_iter_close_container(&m_messageIterator, &arrayIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::beginArgumentRead()
|
||||||
|
{
|
||||||
|
dbus_message_iter_init(m_message, &m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(int &value)
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_INT32) { return; }
|
||||||
|
dbus_int32_t i;
|
||||||
|
dbus_message_iter_get_basic(&m_messageIterator, &i);
|
||||||
|
value = i;
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(bool &value)
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_BOOLEAN) { return; }
|
||||||
|
dbus_bool_t v;
|
||||||
|
dbus_message_iter_get_basic(&m_messageIterator, &v);
|
||||||
|
if (v == TRUE) { value = true; }
|
||||||
|
else { value = false; }
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(double &value)
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_DOUBLE) { return; }
|
||||||
|
dbus_message_iter_get_basic(&m_messageIterator, &value);
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(std::string &value)
|
||||||
|
{
|
||||||
|
const char *str = nullptr;
|
||||||
|
if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_STRING) { return; }
|
||||||
|
dbus_message_iter_get_basic(&m_messageIterator, &str);
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
value = std::string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(std::vector<int> &value)
|
||||||
|
{
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_INT32) { return; }
|
||||||
|
dbus_int32_t i;
|
||||||
|
dbus_message_iter_get_basic(&arrayIterator, &i);
|
||||||
|
value.push_back(i);
|
||||||
|
}
|
||||||
|
while (dbus_message_iter_next(&arrayIterator));
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(std::vector<bool> &value)
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_ARRAY) { return; }
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_BOOLEAN) { return; }
|
||||||
|
dbus_bool_t b;
|
||||||
|
dbus_message_iter_get_basic(&arrayIterator, &b);
|
||||||
|
if (b == TRUE) { value.push_back(true); }
|
||||||
|
else { value.push_back(false); }
|
||||||
|
}
|
||||||
|
while (dbus_message_iter_next(&arrayIterator));
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(std::vector<double> &value)
|
||||||
|
{
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DOUBLE) { return; }
|
||||||
|
double d;
|
||||||
|
dbus_message_iter_get_basic(&arrayIterator, &d);
|
||||||
|
value.push_back(d);
|
||||||
|
}
|
||||||
|
while (dbus_message_iter_next(&arrayIterator));
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusMessage::getArgument(std::vector<std::string> &value)
|
||||||
|
{
|
||||||
|
DBusMessageIter arrayIterator;
|
||||||
|
dbus_message_iter_recurse(&m_messageIterator, &arrayIterator);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING) { return; }
|
||||||
|
const char *str = nullptr;
|
||||||
|
dbus_message_iter_get_basic(&arrayIterator, &str);
|
||||||
|
value.push_back(std::string(str));
|
||||||
|
}
|
||||||
|
while (dbus_message_iter_next(&arrayIterator));
|
||||||
|
dbus_message_iter_next(&m_messageIterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage CDBusMessage::createSignal(const std::string &path, const std::string &interfaceName, const std::string &signalName)
|
||||||
|
{
|
||||||
|
DBusMessage *signal = dbus_message_new_signal(path.c_str(), interfaceName.c_str(), signalName.c_str());
|
||||||
|
return CDBusMessage(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusMessage CDBusMessage::createReply(const std::string &destination, dbus_uint32_t serial)
|
||||||
|
{
|
||||||
|
DBusMessage *reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||||
|
dbus_message_set_no_reply(reply, TRUE);
|
||||||
|
if (! destination.empty()) { dbus_message_set_destination(reply, destination.c_str()); }
|
||||||
|
dbus_message_set_reply_serial(reply, serial);
|
||||||
|
CDBusMessage msg(reply);
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
113
src/Network/Swift/dbusmessage.h
Normal file
113
src/Network/Swift/dbusmessage.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// dbusmessage.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSMESSAGE_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSMESSAGE_H
|
||||||
|
|
||||||
|
#include "dbus/dbus.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
//! DBus Message
|
||||||
|
class CDBusMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
//! @{
|
||||||
|
CDBusMessage(DBusMessage *message);
|
||||||
|
CDBusMessage(const CDBusMessage &other);
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~CDBusMessage();
|
||||||
|
|
||||||
|
//! Assignment operator
|
||||||
|
CDBusMessage &operator=(CDBusMessage other);
|
||||||
|
|
||||||
|
//! Is this message a method call?
|
||||||
|
bool isMethodCall() const;
|
||||||
|
|
||||||
|
//! Does this message want a reply?
|
||||||
|
bool wantsReply() const;
|
||||||
|
|
||||||
|
//! Get the message sender
|
||||||
|
std::string getSender() const;
|
||||||
|
|
||||||
|
//! Get the message serial. This is usally required for reply message.
|
||||||
|
dbus_uint32_t getSerial() const;
|
||||||
|
|
||||||
|
//! Get the called interface name
|
||||||
|
std::string getInterfaceName() const;
|
||||||
|
|
||||||
|
//! Get the called object path
|
||||||
|
std::string getObjectPath() const;
|
||||||
|
|
||||||
|
//! Get the called method name
|
||||||
|
std::string getMethodName() const;
|
||||||
|
|
||||||
|
//! Begin writing argument
|
||||||
|
void beginArgumentWrite();
|
||||||
|
|
||||||
|
//! Append argument. Make sure to call \sa beginArgumentWrite() before.
|
||||||
|
//! @{
|
||||||
|
void appendArgument(bool value);
|
||||||
|
void appendArgument(const char *value);
|
||||||
|
void appendArgument(const std::string &value);
|
||||||
|
void appendArgument(int value);
|
||||||
|
void appendArgument(double value);
|
||||||
|
void appendArgument(const std::vector<double> &array);
|
||||||
|
void appendArgument(const std::vector<std::string> &array);
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Begin reading arguments
|
||||||
|
void beginArgumentRead();
|
||||||
|
|
||||||
|
//! Read single argument. Make sure to call \sa beginArgumentRead() before.
|
||||||
|
//! @{
|
||||||
|
void getArgument(int &value);
|
||||||
|
void getArgument(bool &value);
|
||||||
|
void getArgument(double &value);
|
||||||
|
void getArgument(std::string &value);
|
||||||
|
void getArgument(std::vector<int> &value);
|
||||||
|
void getArgument(std::vector<bool> &value);
|
||||||
|
void getArgument(std::vector<double> &value);
|
||||||
|
void getArgument(std::vector<std::string> &value);
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Creates a DBus message containing a DBus signal
|
||||||
|
static CDBusMessage createSignal(const std::string &path, const std::string &interfaceName, const std::string &signalName);
|
||||||
|
|
||||||
|
//! Creates a DBus message containing a DBus reply
|
||||||
|
static CDBusMessage createReply(const std::string &destination, dbus_uint32_t serial);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class CDBusConnection;
|
||||||
|
|
||||||
|
DBusMessage *m_message = nullptr;
|
||||||
|
DBusMessageIter m_messageIterator;
|
||||||
|
CDBusMessage(DBusMessage *message, dbus_uint32_t serial);
|
||||||
|
dbus_uint32_t m_serial = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
106
src/Network/Swift/dbusobject.cpp
Normal file
106
src/Network/Swift/dbusobject.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
// dbusobject.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbusobject.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
CDBusObject::CDBusObject()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
CDBusObject::~CDBusObject()
|
||||||
|
{
|
||||||
|
if (m_dbusConnection) { m_dbusConnection->unregisterDisconnectedCallback(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
void CDBusObject::setDBusConnection(const std::shared_ptr<CDBusConnection> &dbusConnection)
|
||||||
|
{
|
||||||
|
m_dbusConnection = dbusConnection;
|
||||||
|
dbusConnectedHandler();
|
||||||
|
CDBusConnection::DisconnectedCallback disconnectedHandler = std::bind(&CDBusObject::dbusDisconnectedHandler, this);
|
||||||
|
m_dbusConnection->registerDisconnectedCallback(this, disconnectedHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::registerDBusObjectPath(const std::string &interfaceName, const std::string &objectPath)
|
||||||
|
{
|
||||||
|
assert(m_dbusConnection);
|
||||||
|
m_interfaceName = interfaceName;
|
||||||
|
m_objectPath = objectPath;
|
||||||
|
m_dbusConnection->registerObjectPath(this, interfaceName, objectPath, m_dbusObjectPathVTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::sendDBusSignal(const std::string &name)
|
||||||
|
{
|
||||||
|
if (! m_dbusConnection) { return; }
|
||||||
|
CDBusMessage signal = CDBusMessage::createSignal(m_objectPath, m_interfaceName, name);
|
||||||
|
m_dbusConnection->sendMessage(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::sendDBusMessage(const CDBusMessage &message)
|
||||||
|
{
|
||||||
|
if (! m_dbusConnection) { return; }
|
||||||
|
m_dbusConnection->sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::maybeSendEmptyDBusReply(bool wantsReply, const std::string &destination, dbus_uint32_t serial)
|
||||||
|
{
|
||||||
|
if (wantsReply)
|
||||||
|
{
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(destination, serial);
|
||||||
|
m_dbusConnection->sendMessage(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::queueDBusCall(const std::function<void ()> &func)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
m_qeuedDBusCalls.push_back(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::invokeQueuedDBusCalls()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
while (m_qeuedDBusCalls.size() > 0)
|
||||||
|
{
|
||||||
|
m_qeuedDBusCalls.front()();
|
||||||
|
m_qeuedDBusCalls.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusObject::dbusObjectPathUnregisterFunction(DBusConnection *connection, void *data)
|
||||||
|
{
|
||||||
|
(void)connection; // unused
|
||||||
|
(void)data; // unused
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusHandlerResult CDBusObject::dbusObjectPathMessageFunction(DBusConnection *connection, DBusMessage *message, void *data)
|
||||||
|
{
|
||||||
|
(void)connection; // unused
|
||||||
|
|
||||||
|
auto *obj = static_cast<CDBusObject *>(data);
|
||||||
|
|
||||||
|
DBusError err;
|
||||||
|
dbus_error_init(&err);
|
||||||
|
|
||||||
|
CDBusMessage dbusMessage(message);
|
||||||
|
return obj->dbusMessageHandler(dbusMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
108
src/Network/Swift/dbusobject.h
Normal file
108
src/Network/Swift/dbusobject.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// dbusobject.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSOBJECT_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSOBJECT_H
|
||||||
|
|
||||||
|
#include "dbusconnection.h"
|
||||||
|
#include <mutex>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
//! DBus base object
|
||||||
|
class CDBusObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CDBusObject();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
virtual ~CDBusObject();
|
||||||
|
|
||||||
|
//! Set the assigned DBus connection.
|
||||||
|
//! \remark Currently one object can only manage one connection at a time
|
||||||
|
void setDBusConnection(const std::shared_ptr<CDBusConnection> &dbusConnection);
|
||||||
|
|
||||||
|
//! Register itself with interfaceName and objectPath
|
||||||
|
//! \warning Before calling this method, make sure that a valid DBus connection was set.
|
||||||
|
void registerDBusObjectPath(const std::string &interfaceName, const std::string &objectPath);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! Handler which is called when DBusCconnection is established
|
||||||
|
virtual void dbusConnectedHandler() {}
|
||||||
|
|
||||||
|
//! DBus message handler
|
||||||
|
virtual DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) = 0;
|
||||||
|
|
||||||
|
//! Handler which is called when DBusConnection disconnected
|
||||||
|
virtual void dbusDisconnectedHandler() {}
|
||||||
|
|
||||||
|
//! Send DBus signal
|
||||||
|
void sendDBusSignal(const std::string &name);
|
||||||
|
|
||||||
|
//! Send DBus message
|
||||||
|
void sendDBusMessage(const CDBusMessage &message);
|
||||||
|
|
||||||
|
//! Maybe sends an empty DBus reply (acknowledgement)
|
||||||
|
void maybeSendEmptyDBusReply(bool wantsReply, const std::string &destination, dbus_uint32_t serial);
|
||||||
|
|
||||||
|
//! Send DBus reply
|
||||||
|
template <typename T>
|
||||||
|
void sendDBusReply(const std::string &destination, dbus_uint32_t serial, const T &argument)
|
||||||
|
{
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(destination, serial);
|
||||||
|
reply.beginArgumentWrite();
|
||||||
|
reply.appendArgument(argument);
|
||||||
|
m_dbusConnection->sendMessage(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Send DBus reply
|
||||||
|
template <typename T>
|
||||||
|
void sendDBusReply(const std::string &destination, dbus_uint32_t serial, const std::vector<T> &array)
|
||||||
|
{
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(destination, serial);
|
||||||
|
reply.beginArgumentWrite();
|
||||||
|
reply.appendArgument(array);
|
||||||
|
m_dbusConnection->sendMessage(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Queue a DBus call to be executed in a different thread
|
||||||
|
void queueDBusCall(const std::function<void()> &func);
|
||||||
|
|
||||||
|
//! Invoke all pending DBus calls. They will be executed in the calling thread.
|
||||||
|
void invokeQueuedDBusCalls();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void dbusObjectPathUnregisterFunction(DBusConnection *connection, void *data);
|
||||||
|
static DBusHandlerResult dbusObjectPathMessageFunction(DBusConnection *connection, DBusMessage *message, void *data);
|
||||||
|
|
||||||
|
std::shared_ptr<CDBusConnection> m_dbusConnection;
|
||||||
|
std::string m_interfaceName;
|
||||||
|
std::string m_objectPath;
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
std::deque<std::function<void()>> m_qeuedDBusCalls;
|
||||||
|
|
||||||
|
const DBusObjectPathVTable m_dbusObjectPathVTable = { dbusObjectPathUnregisterFunction, dbusObjectPathMessageFunction, nullptr, nullptr, nullptr, nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
101
src/Network/Swift/dbusserver.cpp
Normal file
101
src/Network/Swift/dbusserver.cpp
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// dbusserver.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "dbusserver.h"
|
||||||
|
#include "dbusobject.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
CDBusServer::CDBusServer()
|
||||||
|
{
|
||||||
|
dbus_threads_init_default();
|
||||||
|
}
|
||||||
|
|
||||||
|
CDBusServer::~CDBusServer()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusServer::listen(const std::string &address)
|
||||||
|
{
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
m_server.reset(dbus_server_listen(address.c_str(), &error));
|
||||||
|
|
||||||
|
if (! m_server)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_server_set_new_connection_function(m_server.get(), onNewConnection, this, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDBusServer::isConnected() const
|
||||||
|
{
|
||||||
|
return m_server ? dbus_server_get_is_connected(m_server.get()) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusServer::close()
|
||||||
|
{
|
||||||
|
if (m_server) { dbus_server_disconnect(m_server.get()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusServer::setDispatcher(CDBusDispatcher *dispatcher)
|
||||||
|
{
|
||||||
|
assert(dispatcher);
|
||||||
|
assert(m_server);
|
||||||
|
|
||||||
|
m_dispatcher = dispatcher;
|
||||||
|
|
||||||
|
dbus_server_set_watch_functions(
|
||||||
|
m_server.get(),
|
||||||
|
dispatcher->m_watchCallbacks.add,
|
||||||
|
dispatcher->m_watchCallbacks.remove,
|
||||||
|
dispatcher->m_watchCallbacks.toggled,
|
||||||
|
&dispatcher->m_watchCallbacks, nullptr);
|
||||||
|
|
||||||
|
dbus_server_set_timeout_functions(
|
||||||
|
m_server.get(),
|
||||||
|
dispatcher->m_timeoutCallbacks.add,
|
||||||
|
dispatcher->m_timeoutCallbacks.remove,
|
||||||
|
dispatcher->m_timeoutCallbacks.toggled,
|
||||||
|
&dispatcher->m_timeoutCallbacks, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusServer::onNewConnection(DBusServer *, DBusConnection *conn)
|
||||||
|
{
|
||||||
|
auto dbusConnection = std::make_shared<CDBusConnection>(conn);
|
||||||
|
m_newConnectionFunc(dbusConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusServer::onNewConnection(DBusServer *server, DBusConnection *conn, void *data)
|
||||||
|
{
|
||||||
|
auto *obj = static_cast<CDBusServer *>(data);
|
||||||
|
obj->onNewConnection(server, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
94
src/Network/Swift/dbusserver.h
Normal file
94
src/Network/Swift/dbusserver.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
// dbusserver.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_DBUSSERVER_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_DBUSSERVER_H
|
||||||
|
|
||||||
|
#include "dbusmessage.h"
|
||||||
|
#include "dbuserror.h"
|
||||||
|
#include "dbuscallbacks.h"
|
||||||
|
#include "dbusdispatcher.h"
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
|
||||||
|
class CDBusObject;
|
||||||
|
|
||||||
|
//! DBus connection
|
||||||
|
class CDBusServer : public IDispatchable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! New connection handler function
|
||||||
|
using NewConnectionFunc = std::function<void(std::shared_ptr<CDBusConnection>)>;
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
CDBusServer();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~CDBusServer();
|
||||||
|
|
||||||
|
//! Set the dispatcher
|
||||||
|
void setDispatcher(CDBusDispatcher *dispatcher);
|
||||||
|
|
||||||
|
//! Connect to bus
|
||||||
|
bool listen(const std::string &address);
|
||||||
|
|
||||||
|
//! Is connected?
|
||||||
|
bool isConnected() const;
|
||||||
|
|
||||||
|
void dispatch() override {}
|
||||||
|
|
||||||
|
//! Close connection
|
||||||
|
void close();
|
||||||
|
|
||||||
|
//! Get the last error
|
||||||
|
CDBusError lastError() const { return m_lastError; }
|
||||||
|
|
||||||
|
//! Set the function to be used for handling new connections.
|
||||||
|
void setNewConnectionFunc(const NewConnectionFunc &func)
|
||||||
|
{
|
||||||
|
m_newConnectionFunc = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onNewConnection(DBusServer *server, DBusConnection *conn);
|
||||||
|
static void onNewConnection(DBusServer *server, DBusConnection *conn, void *data);
|
||||||
|
|
||||||
|
struct DBusServerDeleter
|
||||||
|
{
|
||||||
|
void operator()(DBusServer *obj) const { dbus_server_unref(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
CDBusDispatcher *m_dispatcher = nullptr;
|
||||||
|
std::unique_ptr<DBusServer, DBusServerDeleter> m_server;
|
||||||
|
CDBusError m_lastError;
|
||||||
|
NewConnectionFunc m_newConnectionFunc;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
97
src/Network/Swift/plugin.cpp
Normal file
97
src/Network/Swift/plugin.cpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// plugin.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "service.h"
|
||||||
|
#include "traffic.h"
|
||||||
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
|
#include <simgear/structure/commands.hxx>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <Main/globals.hxx>
|
||||||
|
#include <cmath>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline std::string fgswiftbusServiceName()
|
||||||
|
{
|
||||||
|
return std::string("org.swift-project.fgswiftbus");
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace FGSwiftBus {
|
||||||
|
CPlugin::CPlugin()
|
||||||
|
{
|
||||||
|
startServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
CPlugin::~CPlugin()
|
||||||
|
{
|
||||||
|
m_dbusConnection->close();
|
||||||
|
m_shouldStop = true;
|
||||||
|
if (m_dbusThread.joinable()) { m_dbusThread.join(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlugin::startServer()
|
||||||
|
{
|
||||||
|
|
||||||
|
m_service.reset(new CService());
|
||||||
|
m_traffic.reset(new CTraffic());
|
||||||
|
m_dbusP2PServer.reset(new CDBusServer());
|
||||||
|
|
||||||
|
std::string ip = fgGetString("/sim/swift/adress");
|
||||||
|
std::string port = fgGetString("/sim/swift/port");
|
||||||
|
std::string listenAddress = "tcp:host=" + ip + ",port=" + port;
|
||||||
|
if (! m_dbusP2PServer->listen(listenAddress))
|
||||||
|
{
|
||||||
|
m_service->addTextMessage("XSwiftBus startup failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_dbusP2PServer->setDispatcher(&m_dbusDispatcher);
|
||||||
|
m_dbusP2PServer->setNewConnectionFunc([this](const std::shared_ptr<CDBusConnection>& conn) {
|
||||||
|
m_dbusConnection = conn;
|
||||||
|
m_dbusConnection->setDispatcher(&m_dbusDispatcher);
|
||||||
|
m_service->setDBusConnection(m_dbusConnection);
|
||||||
|
m_service->registerDBusObjectPath(m_service->InterfaceName(), m_service->ObjectPath());
|
||||||
|
m_traffic->setDBusConnection(m_dbusConnection);
|
||||||
|
m_traffic->registerDBusObjectPath(m_traffic->InterfaceName(), m_traffic->ObjectPath());
|
||||||
|
});
|
||||||
|
|
||||||
|
SG_LOG(SG_NETWORK,SG_INFO,"FGSwiftBus started");
|
||||||
|
}
|
||||||
|
|
||||||
|
float CPlugin::startServerDeferred(float, float, int, void* refcon)
|
||||||
|
{
|
||||||
|
auto* plugin = static_cast<CPlugin*>(refcon);
|
||||||
|
if (!plugin->m_isRunning) {
|
||||||
|
plugin->startServer();
|
||||||
|
plugin->m_isRunning = true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlugin::fastLoop()
|
||||||
|
{
|
||||||
|
this->m_dbusDispatcher.runOnce();
|
||||||
|
this->m_service->process();
|
||||||
|
this->m_traffic->process();
|
||||||
|
this->m_traffic->emitSimFrame();
|
||||||
|
}
|
||||||
|
} // namespace FGSwiftBus
|
74
src/Network/Swift/plugin.h
Normal file
74
src/Network/Swift/plugin.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// plugin.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_PLUGIN_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_PLUGIN_H
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \namespace FGSwiftBus
|
||||||
|
* Plugin loaded by Flightgear which publishes a DBus service
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "dbusconnection.h"
|
||||||
|
#include "dbusdispatcher.h"
|
||||||
|
#include "dbusserver.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace FGSwiftBus
|
||||||
|
{
|
||||||
|
class CService;
|
||||||
|
class CTraffic;
|
||||||
|
class CWeather;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Main plugin class
|
||||||
|
*/
|
||||||
|
class CPlugin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CPlugin();
|
||||||
|
void startServer();
|
||||||
|
//! Destructor
|
||||||
|
~CPlugin();
|
||||||
|
static float startServerDeferred(float, float, int, void* refcon);
|
||||||
|
void fastLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDBusDispatcher m_dbusDispatcher;
|
||||||
|
std::unique_ptr<CDBusServer> m_dbusP2PServer;
|
||||||
|
std::shared_ptr<CDBusConnection> m_dbusConnection;
|
||||||
|
std::unique_ptr<CService> m_service;
|
||||||
|
std::unique_ptr<CTraffic> m_traffic;
|
||||||
|
|
||||||
|
std::thread m_dbusThread;
|
||||||
|
bool m_isRunning = false;
|
||||||
|
bool m_shouldStop = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // guard
|
516
src/Network/Swift/service.cpp
Normal file
516
src/Network/Swift/service.cpp
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
// service.cpp - Service module for swift<->FG connection
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "service.h"
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/io/raw_socket.hxx>
|
||||||
|
#include <simgear/misc/stdint.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/structure/commands.hxx>
|
||||||
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
|
namespace FGSwiftBus {
|
||||||
|
|
||||||
|
CService::CService()
|
||||||
|
{
|
||||||
|
SG_LOG(SG_NETWORK, SG_INFO, "FGSwiftBus Service initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CService::InterfaceName() {
|
||||||
|
static const std::string s(FGSWIFTBUS_SERVICE_INTERFACENAME);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CService::ObjectPath()
|
||||||
|
{
|
||||||
|
static const std::string s(FGSWIFTBUS_SERVICE_OBJECTPATH);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::addTextMessage(const std::string& text)
|
||||||
|
{
|
||||||
|
if (text.empty()) { return; }
|
||||||
|
fgSetString("/sim/messages/copilot", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftModelPath() const
|
||||||
|
{
|
||||||
|
return fgGetString("/sim/aircraft-dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftLivery() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftIcaoCode() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftDescription() const
|
||||||
|
{
|
||||||
|
return fgGetString("/sim/description");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::isPaused() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/sim/freeze/master");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getLatitude() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/position/latitude-deg");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getLongitude() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/position/longitude-deg");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getAltitudeMSL() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/position/altitude-ft");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getHeightAGL() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/position/altitude-agl-ft");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getGroundSpeed() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/velocities/groundspeed-kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getPitch() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/orientation/pitch-deg");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getRoll() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/orientation/roll-deg");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getTrueHeading() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/orientation/heading-deg");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getAllWheelsOnGround() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/gear/gear/wow");
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getCom1Active() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/instrumentation/comm/frequencies/selected-mhz") * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getCom1Standby() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/instrumentation/comm/frequencies/standby-mhz") * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getCom2Active() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz") * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getCom2Standby() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/instrumentation/comm[1]/frequencies/standby-mhz") * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getTransponderCode() const
|
||||||
|
{
|
||||||
|
return fgGetInt("/instrumentation/transponder/id-code");
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getTransponderMode() const
|
||||||
|
{
|
||||||
|
return fgGetInt("/instrumentation/transponder/inputs/knob-mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getTransponderIdent() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/instrumentation/transponder/ident");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getBeaconLightsOn() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/controls/lighting/beacon");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getLandingLightsOn() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/controls/lighting/landing-lights");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getNavLightsOn() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/controls/lighting/nav-lights");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CService::getStrobeLightsOn() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/controls/lighting/strobe");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CService::getTaxiLightsOn() const
|
||||||
|
{
|
||||||
|
return fgGetBool("/controls/lighting/taxi-light");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getQNH() const
|
||||||
|
{
|
||||||
|
return fgGetDouble("/environment/pressure-sea-level-inhg");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setCom1Active(int freq)
|
||||||
|
{
|
||||||
|
fgSetDouble("/instrumentation/comm/frequencies/selected-mhz", freq / (double)1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setCom1Standby(int freq)
|
||||||
|
{
|
||||||
|
fgSetDouble("/instrumentation/comm/frequencies/standby-mhz", freq / (double)1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setCom2Active(int freq)
|
||||||
|
{
|
||||||
|
fgSetDouble("/instrumentation/comm[1]/frequencies/selected-mhz", freq / (double)1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setCom2Standby(int freq)
|
||||||
|
{
|
||||||
|
fgSetDouble("/instrumentation/comm[1]/frequencies/standby-mhz", freq / (double)1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setTransponderCode(int code)
|
||||||
|
{
|
||||||
|
fgSetInt("/instrumentation/transponder/id-code", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CService::setTransponderMode(int mode)
|
||||||
|
{
|
||||||
|
fgSetInt("/instrumentation/transponder/inputs/knob-mode", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getFlapsDeployRatio() const
|
||||||
|
{
|
||||||
|
return fgGetFloat("/surface-positions/flap-pos-norm");
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getGearDeployRatio() const
|
||||||
|
{
|
||||||
|
return fgGetFloat("/gear/gear/position-norm");
|
||||||
|
}
|
||||||
|
|
||||||
|
int CService::getNumberOfEngines() const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> CService::getEngineN1Percentage() const
|
||||||
|
{
|
||||||
|
std::vector<double> list;
|
||||||
|
const auto number = static_cast<unsigned int>(getNumberOfEngines());
|
||||||
|
list.reserve(number);
|
||||||
|
for (unsigned int engineNumber = 0; engineNumber < number; ++engineNumber) {
|
||||||
|
list.push_back(fgGetDouble("/engine/engine/n1"));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CService::getSpeedBrakeRatio() const
|
||||||
|
{
|
||||||
|
return fgGetFloat("/surface-positions/speedbrake-pos-norm");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftModelFilename() const
|
||||||
|
{
|
||||||
|
std::string modelFileName = fgGetString("/sim/aircraft");
|
||||||
|
modelFileName.append("-set.xml");
|
||||||
|
return modelFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftModelString() const
|
||||||
|
{
|
||||||
|
std::string modelName = fgGetString("/sim/aircraft");
|
||||||
|
std::string modelString = "FG " + modelName;
|
||||||
|
return modelString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CService::getAircraftName() const
|
||||||
|
{
|
||||||
|
return fgGetString("/sim/aircraft");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* introspection_service = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
|
||||||
|
|
||||||
|
DBusHandlerResult CService::dbusMessageHandler(const CDBusMessage& message_)
|
||||||
|
{
|
||||||
|
CDBusMessage message(message_);
|
||||||
|
const std::string sender = message.getSender();
|
||||||
|
const dbus_uint32_t serial = message.getSerial();
|
||||||
|
const bool wantsReply = message.wantsReply();
|
||||||
|
|
||||||
|
if (message.getInterfaceName() == DBUS_INTERFACE_INTROSPECTABLE) {
|
||||||
|
if (message.getMethodName() == "Introspect") {
|
||||||
|
sendDBusReply(sender, serial, introspection_service);
|
||||||
|
}
|
||||||
|
} else if (message.getInterfaceName() == FGSWIFTBUS_SERVICE_INTERFACENAME) {
|
||||||
|
if (message.getMethodName() == "addTextMessage") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
std::string text;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(text);
|
||||||
|
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
addTextMessage(text);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getOwnAircraftSituationData") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
double lat = getLatitude();
|
||||||
|
double lon = getLongitude();
|
||||||
|
double alt = getAltitudeMSL();
|
||||||
|
double gs = getGroundSpeed();
|
||||||
|
double pitch = getPitch();
|
||||||
|
double roll = getRoll();
|
||||||
|
double trueHeading = getTrueHeading();
|
||||||
|
double qnh = getQNH();
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(sender, serial);
|
||||||
|
reply.beginArgumentWrite();
|
||||||
|
reply.appendArgument(lat);
|
||||||
|
reply.appendArgument(lon);
|
||||||
|
reply.appendArgument(alt);
|
||||||
|
reply.appendArgument(gs);
|
||||||
|
reply.appendArgument(pitch);
|
||||||
|
reply.appendArgument(roll);
|
||||||
|
reply.appendArgument(trueHeading);
|
||||||
|
reply.appendArgument(qnh);
|
||||||
|
sendDBusMessage(reply);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftModelPath") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftModelPath());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftModelFilename") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftModelFilename());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftModelString") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftModelString());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftName") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftName());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftLivery") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftLivery());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftIcaoCode") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftIcaoCode());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAircraftDescription") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAircraftDescription());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "isPaused") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, isPaused());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getLatitudeDeg") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getLatitude());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getLongitudeDeg") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getLongitude());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAltitudeMslFt") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAltitudeMSL());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getHeightAglFt") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getHeightAGL());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getGroundSpeedKts") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getGroundSpeed());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getPitchDeg") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getPitch());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getRollDeg") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getRoll());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getAllWheelsOnGround") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getAllWheelsOnGround());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getCom1ActiveKhz") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getCom1Active());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getCom1StandbyKhz") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getCom1Standby());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getCom2ActiveKhz") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getCom2Active());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getCom2StandbyKhz") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getCom2Standby());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getTransponderCode") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getTransponderCode());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getTransponderMode") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getTransponderMode());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getTransponderIdent") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getTransponderIdent());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getBeaconLightsOn") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getBeaconLightsOn());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getLandingLightsOn") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getLandingLightsOn());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getNavLightsOn") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getNavLightsOn());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getStrobeLightsOn") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getStrobeLightsOn());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getTaxiLightsOn") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getTaxiLightsOn());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getQNHInHg") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getQNH());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setCom1ActiveKhz") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int frequency = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(frequency);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setCom1Active(frequency);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setCom1StandbyKhz") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int frequency = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(frequency);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setCom1Standby(frequency);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setCom2ActiveKhz") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int frequency = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(frequency);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setCom2Active(frequency);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setCom2StandbyKhz") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int frequency = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(frequency);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setCom2Standby(frequency);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setTransponderCode") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int code = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(code);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setTransponderCode(code);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setTransponderMode") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
int mode = 0;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(mode);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
setTransponderMode(mode);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getFlapsDeployRatio") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getFlapsDeployRatio());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getGearDeployRatio") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getGearDeployRatio());
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getEngineN1Percentage") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
std::vector<double> array = getEngineN1Percentage();
|
||||||
|
sendDBusReply(sender, serial, array);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getSpeedBrakeRatio") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
sendDBusReply(sender, serial, getSpeedBrakeRatio());
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Unknown message. Tell DBus that we cannot handle it
|
||||||
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CService::process()
|
||||||
|
{
|
||||||
|
invokeQueuedDBusCalls();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FGSwiftBus
|
202
src/Network/Swift/service.h
Normal file
202
src/Network/Swift/service.h
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
// service.h - Service module for swift<->FG connection
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_SERVICE_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_SERVICE_H
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "dbusobject.h"
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/io/raw_socket.hxx>
|
||||||
|
#include <simgear/misc/stdint.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/structure/commands.hxx>
|
||||||
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
|
|
||||||
|
//! \cond PRIVATE
|
||||||
|
#define FGSWIFTBUS_SERVICE_INTERFACENAME "org.swift_project.fgswiftbus.service"
|
||||||
|
#define FGSWIFTBUS_SERVICE_OBJECTPATH "/fgswiftbus/service"
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
namespace FGSwiftBus {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* FGSwiftBus service object which is accessible through DBus
|
||||||
|
*/
|
||||||
|
class CService : public CDBusObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CService();
|
||||||
|
|
||||||
|
//! DBus interface name
|
||||||
|
static const std::string& InterfaceName();
|
||||||
|
|
||||||
|
//! DBus object path
|
||||||
|
static const std::string& ObjectPath();
|
||||||
|
|
||||||
|
////! Add a text message to the on-screen display, with RGB components in the range [0,1]
|
||||||
|
void addTextMessage(const std::string& text);
|
||||||
|
|
||||||
|
////! Get full path to current aircraft model
|
||||||
|
std::string getAircraftModelPath() const;
|
||||||
|
|
||||||
|
////! Get base filename of current aircraft model
|
||||||
|
std::string getAircraftModelFilename() const;
|
||||||
|
|
||||||
|
////! Get canonical swift model string of current aircraft model
|
||||||
|
std::string getAircraftModelString() const;
|
||||||
|
|
||||||
|
////! Get name of current aircraft model
|
||||||
|
std::string getAircraftName() const;
|
||||||
|
|
||||||
|
////! Get path to current aircraft livery
|
||||||
|
std::string getAircraftLivery() const;
|
||||||
|
|
||||||
|
//! Get the ICAO code of the current aircraft model
|
||||||
|
std::string getAircraftIcaoCode() const;
|
||||||
|
|
||||||
|
////! Get the description of the current aircraft model
|
||||||
|
std::string getAircraftDescription() const;
|
||||||
|
|
||||||
|
//! True if sim is paused
|
||||||
|
bool isPaused() const;
|
||||||
|
|
||||||
|
//! Get aircraft latitude in degrees
|
||||||
|
double getLatitude() const;
|
||||||
|
|
||||||
|
//! Get aircraft longitude in degrees
|
||||||
|
double getLongitude() const;
|
||||||
|
|
||||||
|
//! Get aircraft altitude in feet
|
||||||
|
double getAltitudeMSL() const;
|
||||||
|
|
||||||
|
//! Get aircraft height in feet
|
||||||
|
double getHeightAGL() const;
|
||||||
|
|
||||||
|
//! Get aircraft groundspeed in knots
|
||||||
|
double getGroundSpeed() const;
|
||||||
|
|
||||||
|
//! Get aircraft pitch in degrees above horizon
|
||||||
|
double getPitch() const;
|
||||||
|
|
||||||
|
//! Get aircraft roll in degrees
|
||||||
|
double getRoll() const;
|
||||||
|
|
||||||
|
//! Get aircraft true heading in degrees
|
||||||
|
double getTrueHeading() const;
|
||||||
|
|
||||||
|
//! Get whether all wheels are on the ground
|
||||||
|
bool getAllWheelsOnGround() const;
|
||||||
|
|
||||||
|
//! Get the current COM1 active frequency in kHz
|
||||||
|
int getCom1Active() const;
|
||||||
|
|
||||||
|
//! Get the current COM1 standby frequency in kHz
|
||||||
|
int getCom1Standby() const;
|
||||||
|
|
||||||
|
//! Get the current COM2 active frequency in kHz
|
||||||
|
int getCom2Active() const;
|
||||||
|
|
||||||
|
//! Get the current COM2 standby frequency in kHz
|
||||||
|
int getCom2Standby() const;
|
||||||
|
|
||||||
|
//! Get the current transponder code in decimal
|
||||||
|
int getTransponderCode() const;
|
||||||
|
|
||||||
|
//! Get the current transponder mode (depends on the aircraft, 0-2 usually mean standby, >2 active)
|
||||||
|
int getTransponderMode() const;
|
||||||
|
|
||||||
|
//! Get whether we are currently squawking ident
|
||||||
|
bool getTransponderIdent() const;
|
||||||
|
|
||||||
|
//! Get whether beacon lights are on
|
||||||
|
bool getBeaconLightsOn() const;
|
||||||
|
|
||||||
|
//! Get whether landing lights are on
|
||||||
|
bool getLandingLightsOn() const;
|
||||||
|
|
||||||
|
//! Get whether nav lights are on
|
||||||
|
bool getNavLightsOn() const;
|
||||||
|
|
||||||
|
//! Get whether strobe lights are on
|
||||||
|
bool getStrobeLightsOn() const;
|
||||||
|
|
||||||
|
//! Get whether taxi lights are on
|
||||||
|
bool getTaxiLightsOn() const;
|
||||||
|
|
||||||
|
//! Get barometric pressure at sea level in inches of mercury.
|
||||||
|
double getQNH() const;
|
||||||
|
|
||||||
|
//! Set the current COM1 active frequency in kHz
|
||||||
|
void setCom1Active(int freq);
|
||||||
|
|
||||||
|
//! Set the current COM1 standby frequency in kHz
|
||||||
|
void setCom1Standby(int freq);
|
||||||
|
|
||||||
|
//! Set the current COM2 active frequency in kHz
|
||||||
|
void setCom2Active(int freq);
|
||||||
|
|
||||||
|
//! Set the current COM2 standby frequency in kHz
|
||||||
|
void setCom2Standby(int freq);
|
||||||
|
|
||||||
|
////! Set the current transponder code in decimal
|
||||||
|
void setTransponderCode(int code);
|
||||||
|
|
||||||
|
////! Set the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby, >1 active)
|
||||||
|
void setTransponderMode(int mode);
|
||||||
|
|
||||||
|
//! Get flaps deploy ratio, where 0.0 is flaps fully retracted, and 1.0 is flaps fully extended.
|
||||||
|
double getFlapsDeployRatio() const;
|
||||||
|
|
||||||
|
//! Get gear deploy ratio, where 0 is up and 1 is down
|
||||||
|
double getGearDeployRatio() const;
|
||||||
|
|
||||||
|
//! Get the number of engines of current aircraft
|
||||||
|
int getNumberOfEngines() const;
|
||||||
|
|
||||||
|
//! Get the N1 speed as percent of max (per engine)
|
||||||
|
std::vector<double> getEngineN1Percentage() const;
|
||||||
|
|
||||||
|
//! Get the ratio how much the speedbrakes surfaces are extended (0.0 is fully retracted, and 1.0 is fully extended)
|
||||||
|
double getSpeedBrakeRatio() const;
|
||||||
|
|
||||||
|
//! Perform generic processing
|
||||||
|
int process();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DBusHandlerResult dbusMessageHandler(const CDBusMessage& message) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
} // namespace FGSwiftBus
|
||||||
|
|
||||||
|
#endif // guard
|
104
src/Network/Swift/swift_connection.cxx
Normal file
104
src/Network/Swift/swift_connection.cxx
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// swift_connection.cxx
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "swift_connection.hxx"
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/io/raw_socket.hxx>
|
||||||
|
#include <simgear/misc/stdint.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/structure/commands.hxx>
|
||||||
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline std::string fgswiftbusServiceName()
|
||||||
|
{
|
||||||
|
return std::string("org.swift-project.fgswiftbus");
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool SwiftConnection::startServer(const SGPropertyNode* arg, SGPropertyNode* root)
|
||||||
|
{
|
||||||
|
SwiftConnection::plug = new FGSwiftBus::CPlugin();
|
||||||
|
serverRunning = true;
|
||||||
|
fgSetBool("/sim/swift/serverRunning", true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SwiftConnection::stopServer(const SGPropertyNode* arg, SGPropertyNode* root)
|
||||||
|
{
|
||||||
|
SwiftConnection::plug->~CPlugin();
|
||||||
|
fgSetBool("/sim/swift/serverRunning", false);
|
||||||
|
serverRunning = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwiftConnection::SwiftConnection()
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SwiftConnection::~SwiftConnection()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwiftConnection::init(void)
|
||||||
|
{
|
||||||
|
if (initialized == false) {
|
||||||
|
globals->get_commands()->addCommand("swiftStart", this, &SwiftConnection::startServer);
|
||||||
|
globals->get_commands()->addCommand("swiftStop", this, &SwiftConnection::stopServer);
|
||||||
|
fgSetBool("/sim/swift/available", true);
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwiftConnection::update(double delta_time_sec)
|
||||||
|
{
|
||||||
|
if (serverRunning == true) {
|
||||||
|
SwiftConnection::plug->fastLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwiftConnection::shutdown(void)
|
||||||
|
{
|
||||||
|
if (initialized == true) {
|
||||||
|
globals->get_commands()->removeCommand("swiftStart");
|
||||||
|
globals->get_commands()->removeCommand("swiftStop");
|
||||||
|
fgSetBool("/sim/swift/available", false);
|
||||||
|
initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwiftConnection::reinit()
|
||||||
|
{
|
||||||
|
shutdown();
|
||||||
|
init();
|
||||||
|
}
|
57
src/Network/Swift/swift_connection.hxx
Normal file
57
src/Network/Swift/swift_connection.hxx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// swift_conection.hxx
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef SWIFT_CONNECTION_H
|
||||||
|
#define SWIFT_CONNECTION_H
|
||||||
|
#include "dbusconnection.h"
|
||||||
|
#include "dbusdispatcher.h"
|
||||||
|
#include <Main/fg_props.hxx>
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/io/raw_socket.hxx>
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "dbusserver.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SwiftConnection : public SGSubsystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool startServer(const SGPropertyNode* arg, SGPropertyNode* root);
|
||||||
|
bool stopServer(const SGPropertyNode* arg, SGPropertyNode* root);
|
||||||
|
SwiftConnection();
|
||||||
|
~SwiftConnection();
|
||||||
|
FGSwiftBus::CPlugin* plug;
|
||||||
|
|
||||||
|
virtual void init(void);
|
||||||
|
virtual void update(double delta_time_sec) override;
|
||||||
|
virtual void shutdown(void);
|
||||||
|
virtual void reinit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool serverRunning = false;
|
||||||
|
bool initialized = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
264
src/Network/Swift/traffic.cpp
Normal file
264
src/Network/Swift/traffic.cpp
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
// traffic.cpp - Traffic module for swift<->FG connection
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
//! \cond PRIVATE
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#include "traffic.h"
|
||||||
|
#include "SwiftAircraftManager.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
// clazy:excludeall=reserve-candidates
|
||||||
|
|
||||||
|
namespace FGSwiftBus {
|
||||||
|
|
||||||
|
CTraffic::CTraffic()
|
||||||
|
{
|
||||||
|
acm = new FGSwiftAircraftManager();
|
||||||
|
SG_LOG(SG_NETWORK, SG_INFO, "FGSwiftBus Traffic started");
|
||||||
|
}
|
||||||
|
|
||||||
|
CTraffic::~CTraffic()
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
SG_LOG(SG_NETWORK, SG_INFO, "FGSwiftBus Traffic stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CTraffic::InterfaceName()
|
||||||
|
{
|
||||||
|
static std::string s(FGSWIFTBUS_TRAFFIC_INTERFACENAME);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CTraffic::ObjectPath()
|
||||||
|
{
|
||||||
|
static std::string s(FGSWIFTBUS_TRAFFIC_OBJECTPATH);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::planeLoaded(void* id, bool succeeded, void* self)
|
||||||
|
{
|
||||||
|
auto* traffic = static_cast<CTraffic*>(self);
|
||||||
|
auto planeIt = traffic->m_planesById.find(id);
|
||||||
|
if (planeIt == traffic->m_planesById.end()) { return; }
|
||||||
|
|
||||||
|
if (succeeded) {
|
||||||
|
traffic->emitPlaneAdded(planeIt->second->callsign);
|
||||||
|
} else {
|
||||||
|
traffic->emitPlaneAddingFailed(planeIt->second->callsign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTraffic::initialize()
|
||||||
|
{
|
||||||
|
m_initialized = true;
|
||||||
|
|
||||||
|
m_enabled = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::emitSimFrame()
|
||||||
|
{
|
||||||
|
if (m_emitSimFrame) { sendDBusSignal("simFrame"); }
|
||||||
|
m_emitSimFrame = !m_emitSimFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::emitPlaneAdded(const std::string& callsign)
|
||||||
|
{
|
||||||
|
CDBusMessage signalPlaneAdded = CDBusMessage::createSignal(FGSWIFTBUS_TRAFFIC_OBJECTPATH, FGSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftAdded");
|
||||||
|
signalPlaneAdded.beginArgumentWrite();
|
||||||
|
signalPlaneAdded.appendArgument(callsign);
|
||||||
|
sendDBusMessage(signalPlaneAdded);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::emitPlaneAddingFailed(const std::string& callsign)
|
||||||
|
{
|
||||||
|
CDBusMessage signalPlaneAddingFailed = CDBusMessage::createSignal(FGSWIFTBUS_TRAFFIC_OBJECTPATH, FGSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftAddingFailed");
|
||||||
|
signalPlaneAddingFailed.beginArgumentWrite();
|
||||||
|
signalPlaneAddingFailed.appendArgument(callsign);
|
||||||
|
sendDBusMessage(signalPlaneAddingFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::cleanup()
|
||||||
|
{
|
||||||
|
acm->removeAllPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::removeAllPlanes()
|
||||||
|
{
|
||||||
|
acm->removeAllPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTraffic::dbusDisconnectedHandler()
|
||||||
|
{
|
||||||
|
acm->removeAllPlanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* introspection_traffic = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
|
||||||
|
|
||||||
|
DBusHandlerResult CTraffic::dbusMessageHandler(const CDBusMessage& message_)
|
||||||
|
{
|
||||||
|
CDBusMessage message(message_);
|
||||||
|
const std::string sender = message.getSender();
|
||||||
|
const dbus_uint32_t serial = message.getSerial();
|
||||||
|
const bool wantsReply = message.wantsReply();
|
||||||
|
std::string test = message.getMethodName();
|
||||||
|
|
||||||
|
if (message.getInterfaceName() == DBUS_INTERFACE_INTROSPECTABLE) {
|
||||||
|
if (message.getMethodName() == "Introspect") {
|
||||||
|
sendDBusReply(sender, serial, introspection_traffic);
|
||||||
|
}
|
||||||
|
} else if (message.getInterfaceName() == FGSWIFTBUS_TRAFFIC_INTERFACENAME) {
|
||||||
|
if (message.getMethodName() == "acquireMultiplayerPlanes") {
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
std::string owner;
|
||||||
|
bool acquired = true;
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(sender, serial);
|
||||||
|
reply.beginArgumentWrite();
|
||||||
|
reply.appendArgument(acquired);
|
||||||
|
reply.appendArgument(owner);
|
||||||
|
sendDBusMessage(reply);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "initialize") {
|
||||||
|
sendDBusReply(sender, serial, initialize());
|
||||||
|
} else if (message.getMethodName() == "cleanup") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "addPlane") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
std::string callsign;
|
||||||
|
std::string modelName;
|
||||||
|
std::string aircraftIcao;
|
||||||
|
std::string airlineIcao;
|
||||||
|
std::string livery;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(callsign);
|
||||||
|
message.getArgument(modelName);
|
||||||
|
message.getArgument(aircraftIcao);
|
||||||
|
message.getArgument(airlineIcao);
|
||||||
|
message.getArgument(livery);
|
||||||
|
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
if (acm->addPlane(callsign, modelName)) {
|
||||||
|
emitPlaneAdded(callsign);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "removePlane") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
std::string callsign;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(callsign);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
acm->removePlane(callsign);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "removeAllPlanes") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
acm->removeAllPlanes();
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "setPlanesPositions") {
|
||||||
|
maybeSendEmptyDBusReply(wantsReply, sender, serial);
|
||||||
|
std::vector<std::string> callsigns;
|
||||||
|
std::vector<double> latitudes;
|
||||||
|
std::vector<double> longitudes;
|
||||||
|
std::vector<double> altitudes;
|
||||||
|
std::vector<double> pitches;
|
||||||
|
std::vector<double> rolls;
|
||||||
|
std::vector<double> headings;
|
||||||
|
std::vector<bool> onGrounds;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(callsigns);
|
||||||
|
message.getArgument(latitudes);
|
||||||
|
message.getArgument(longitudes);
|
||||||
|
message.getArgument(altitudes);
|
||||||
|
message.getArgument(pitches);
|
||||||
|
message.getArgument(rolls);
|
||||||
|
message.getArgument(headings);
|
||||||
|
message.getArgument(onGrounds);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
std::vector<SGGeod> positions;
|
||||||
|
std::vector<SGVec3d> orientations;
|
||||||
|
for (int i = 0; i < latitudes.size(); i++) {
|
||||||
|
SGGeod newPos;
|
||||||
|
newPos.setLatitudeDeg(latitudes.at(i));
|
||||||
|
newPos.setLongitudeDeg(longitudes.at(i));
|
||||||
|
newPos.setElevationFt(altitudes.at(i));
|
||||||
|
SGVec3d vec(pitches.at(i), rolls.at(i), headings.at(i));
|
||||||
|
|
||||||
|
positions.push_back(newPos);
|
||||||
|
orientations.push_back(vec);
|
||||||
|
}
|
||||||
|
acm->updatePlanes(callsigns, positions, orientations, onGrounds);
|
||||||
|
});
|
||||||
|
} else if (message.getMethodName() == "getRemoteAircraftData") {
|
||||||
|
std::vector<std::string> requestedcallsigns;
|
||||||
|
message.beginArgumentRead();
|
||||||
|
message.getArgument(requestedcallsigns);
|
||||||
|
queueDBusCall([=]() {
|
||||||
|
std::vector<std::string> callsigns = requestedcallsigns;
|
||||||
|
std::vector<double> latitudesDeg;
|
||||||
|
std::vector<double> longitudesDeg;
|
||||||
|
std::vector<double> elevationsM;
|
||||||
|
std::vector<double> verticalOffsets;
|
||||||
|
acm->getRemoteAircraftData(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets);
|
||||||
|
CDBusMessage reply = CDBusMessage::createReply(sender, serial);
|
||||||
|
reply.beginArgumentWrite();
|
||||||
|
reply.appendArgument(callsigns);
|
||||||
|
reply.appendArgument(latitudesDeg);
|
||||||
|
reply.appendArgument(longitudesDeg);
|
||||||
|
reply.appendArgument(elevationsM);
|
||||||
|
reply.appendArgument(verticalOffsets);
|
||||||
|
sendDBusMessage(reply);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Unknown message. Tell DBus that we cannot handle it
|
||||||
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTraffic::process()
|
||||||
|
{
|
||||||
|
invokeQueuedDBusCalls();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! memcmp function which ignores the header ("size" member) and compares only the payload (the rest of the struct)
|
||||||
|
template <typename T>
|
||||||
|
int memcmpPayload(T* dst, T* src)
|
||||||
|
{
|
||||||
|
return std::memcmp(reinterpret_cast<char*>(dst) + sizeof(dst->size),
|
||||||
|
reinterpret_cast<char*>(src) + sizeof(src->size),
|
||||||
|
sizeof(*dst) - sizeof(dst->size));
|
||||||
|
}
|
||||||
|
} // namespace FGSwiftBus
|
||||||
|
|
||||||
|
//! \endcond
|
108
src/Network/Swift/traffic.h
Normal file
108
src/Network/Swift/traffic.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// traffic.h - Traffic module for swift<->FG connection
|
||||||
|
//
|
||||||
|
// Copyright (C) 2019 - swift Project Community / Contributors (http://swift-project.org/)
|
||||||
|
// Adapted to Flightgear by Lars Toenning <dev@ltoenning.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef BLACKSIM_FGSWIFTBUS_TRAFFIC_H
|
||||||
|
#define BLACKSIM_FGSWIFTBUS_TRAFFIC_H
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
#include "SwiftAircraftManager.h"
|
||||||
|
#include "dbusobject.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
//! \cond PRIVATE
|
||||||
|
#define FGSWIFTBUS_TRAFFIC_INTERFACENAME "org.swift_project.fgswiftbus.traffic"
|
||||||
|
#define FGSWIFTBUS_TRAFFIC_OBJECTPATH "/fgswiftbus/traffic"
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
namespace FGSwiftBus {
|
||||||
|
/*!
|
||||||
|
* FGSwiftBus service object for traffic aircraft which is accessible through DBus
|
||||||
|
*/
|
||||||
|
class CTraffic : public CDBusObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
CTraffic();
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~CTraffic() override;
|
||||||
|
|
||||||
|
//! DBus interface name
|
||||||
|
static const std::string& InterfaceName();
|
||||||
|
|
||||||
|
//! DBus object path
|
||||||
|
static const std::string& ObjectPath();
|
||||||
|
|
||||||
|
//! Initialize the multiplayer planes rendering and return true if successful
|
||||||
|
bool initialize();
|
||||||
|
|
||||||
|
//! Remove all traffic aircraft
|
||||||
|
void removeAllPlanes();
|
||||||
|
|
||||||
|
//! Perform generic processing
|
||||||
|
int process();
|
||||||
|
|
||||||
|
void emitSimFrame();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void dbusDisconnectedHandler() override;
|
||||||
|
|
||||||
|
DBusHandlerResult dbusMessageHandler(const CDBusMessage& message) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_initialized = false;
|
||||||
|
bool m_enabled = false;
|
||||||
|
|
||||||
|
void emitPlaneAdded(const std::string& callsign);
|
||||||
|
void emitPlaneAddingFailed(const std::string& callsign);
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
struct Plane {
|
||||||
|
void* id = nullptr;
|
||||||
|
std::string callsign;
|
||||||
|
std::string aircraftIcao;
|
||||||
|
std::string airlineIcao;
|
||||||
|
std::string livery;
|
||||||
|
std::string modelName;
|
||||||
|
bool hasSurfaces = false;
|
||||||
|
bool hasXpdr = false;
|
||||||
|
char label[32]{};
|
||||||
|
float targetGearPosition = 0;
|
||||||
|
std::chrono::system_clock::time_point prevSurfacesLerpTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Plane*> m_planesByCallsign;
|
||||||
|
std::unordered_map<void*, Plane*> m_planesById;
|
||||||
|
std::vector<std::string> m_followPlaneViewSequence;
|
||||||
|
std::chrono::system_clock::time_point m_timestampLastSimFrame = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
std::string m_followPlaneViewCallsign;
|
||||||
|
|
||||||
|
bool m_emitSimFrame = true;
|
||||||
|
|
||||||
|
|
||||||
|
FGSwiftAircraftManager* acm;
|
||||||
|
|
||||||
|
static void planeLoaded(void* id, bool succeeded, void* self);
|
||||||
|
};
|
||||||
|
} // namespace FGSwiftBus
|
||||||
|
|
||||||
|
#endif // guard
|
Loading…
Reference in a new issue