Version 1.3-rc.1 (#138)

* Minor improvements to the handling of landing gear by the SetGear and HandlePOSI functions

* sendPOSI command change (double for lat/lon/h) (#111)

* Updated POSI to use doubles for lat/lon/alt, as step size for floats was unacceptably large at high longitudes.

* Updated Java library for MATLAB, updated Java project, and updated Windows plugin binaries

* Rolled back Java version to 1.7 for MATLAB compatibility

* Update MessageHandlers.cpp

* Update DataManager.cpp

* Added pause functionality for individual a/c

Adds new cases such that:
0: Unpauses all a/c
1: Pauses all a/c
2: Switches case for all a/c
100:119: Pauses a/c 0:19
200:219: Unpauses a/c 0:19

Updates log messages.

Keeps the 0,1,2 arguments as they previously were.

* Finished individual pause functionality

* Update DataManager.cpp

* Updated flags to allow for individual pause commands

* Individual pause command documentation

* Updated flags to allow for individual pause commands

* Adding individual pause to documentation

* Updated flags to allow for individual pause commands

* Requested changes, cleaning

* Update CMakeLists.txt

Include "-fno-stack-protector" for linking and compiling for systems that do not have this have this flag as a default.

* Enabling AI after setting position (#118)

Previously, the code enabled the AI before setting the position of a/c, which negated its purpose.

* Updated XPlane SDK to version 2.1.3

* Resolve function ambiguity for std::abs on mac

Fixes #126

* Update copyright notice

* Update Windows binaries

* Update Linux binaries

* Update version numbers

* fix osx abs ambiguity (#142)

* fix indexing error (#143)

* Runway camera location control (#144)

* update ignore

* basics working

* set cam pos remotely

* log cam position

* keep default behaviour, if short view message is received

Compatibility with existing software

* all to tabs

* rename variable

* option to use camera direction fields

* Added UDP multicast for plugin discovery (#153)

* Added Timer

* Added UDPSocket::GetAddr

* Added MessageHandlers::SendBeacon()

* PoC of starting a timer on PluginEnable

* C++11

* Added Timer to xcode project

* C++11 in cmake

* added Timer to cmake

* use function pointer in Timer

* moved Timer to namespace

+ wait for thread to join when stopping the timer

* Windows: changed uint to unisgned short

* Windows: Added Timer.h/cpp to project

* GetAddr static

* Send xplane and plugin version with BECN

* SendBeacon with params

* fixed file copyrights

* Include functional

to fix Linux compile error

* review fixes

* Send plugin receive port in BECN

* review fixes

* Fixed tabs vs spaces indentations (#157)

* Java client BECN implementation (#155)

* Added MS Azure Dev Ops CI integration (#162)

* Do not build for i386 on macOS

Use ARCHS_STANDARD  to avoid the error “The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture.”

* Fixed missing include

The Visual Studio solution was not compiling

* Fixed isnan ambigious refernce

Ambigious reference when compiling on travis

https://stackoverflow.com/questions/33770374/why-is-isnan-ambiguous-and-how-to-avoid-it

* Set MSVC warning level to 3

Too many warnings were generated when building a Release build making Travis job to fail because of too much output

* Use default toolset for Visual Studio

AppVeyor recommends to set the default toolset

* #include <cstdint>

* Use MSVC ToolsVersion="14.0"

# Conflicts:
#	xpcPlugin/xpcPlugin/xpcPlugin.vcxproj

* Removed binaries from repository

# Conflicts:
#	xpcPlugin/XPlaneConnect/64/win.xpl
#	xpcPlugin/XPlaneConnect/win.xpl

* Added ms azure ci

xcode

linux

linux + macos

linux + macos

removed branch filter

win tests

win tests

Test all platfroms

artifacts tests

* output all binaries to ‘XPlaneConnect’

All platforms produce a binary in
xpcPlugin/XPlaneConnect/
xpcPlugin/XPlaneConnect/64/

* Added ms azure GH deploy

deploy stage

GH release test

trigger tags

* Clean up yml file

- Added variables
- Added job decriptions

* Ignore script to ignore .exp files

+ fixed output path

* Renamed ms azure GH connection

* Update service connection for azure pipeline

* Added Python3 compatible xpc client. (#156)

* Update Azure Pipelines service connection
This commit is contained in:
Jason Watkins
2019-07-20 08:43:51 -07:00
committed by GitHub
parent 3ed3f8b014
commit a3be4cb1b6
92 changed files with 1937 additions and 375 deletions

View File

@@ -10,6 +10,10 @@ add_definitions(-DXPLM200 -DLIN=1)
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)
SET(CMAKE_CXX_STANDARD 11)
SET(XPC_OUTPUT_DIR "XPlaneConnect")
SET(XPC_OUTPUT_NAME "lin")
add_library(xpc64 SHARED XPCPlugin.cpp
DataManager.cpp
@@ -17,9 +21,12 @@ add_library(xpc64 SHARED XPCPlugin.cpp
Log.cpp
Message.cpp
MessageHandlers.cpp
Timer.cpp
UDPSocket.cpp)
set_target_properties(xpc64 PROPERTIES PREFIX "" SUFFIX ".xpl")
set_target_properties(xpc64 PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-shared -rdynamic -nodefaultlibs -undefined_warning -m64")
set_target_properties(xpc64 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${XPC_OUTPUT_DIR}/64)
set_target_properties(xpc64 PROPERTIES OUTPUT_NAME ${XPC_OUTPUT_NAME})
set_target_properties(xpc64 PROPERTIES COMPILE_FLAGS "-m64 -fno-stack-protector" LINK_FLAGS "-shared -rdynamic -nodefaultlibs -undefined_warning -m64 -fno-stack-protector")
add_library(xpc32 SHARED XPCPlugin.cpp
DataManager.cpp
@@ -27,9 +34,12 @@ add_library(xpc32 SHARED XPCPlugin.cpp
Log.cpp
Message.cpp
MessageHandlers.cpp
Timer.cpp
UDPSocket.cpp)
set_target_properties(xpc32 PROPERTIES PREFIX "" SUFFIX ".xpl")
set_target_properties(xpc32 PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-shared -rdynamic -nodefaultlibs -undefined_warning -m32")
set_target_properties(xpc32 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${XPC_OUTPUT_DIR})
set_target_properties(xpc32 PROPERTIES OUTPUT_NAME ${XPC_OUTPUT_NAME})
set_target_properties(xpc32 PROPERTIES COMPILE_FLAGS "-m32 -fno-stack-protector" LINK_FLAGS "-shared -rdynamic -nodefaultlibs -undefined_warning -m32 -fno-stack-protector")
# Switch install targets when uncommenting the 32 bit line above.
install(TARGETS xpc64 DESTINATION XPlaneConnect/64 RENAME lin.xpl)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
//
// X-Plane API
@@ -109,7 +109,7 @@ namespace XPC
drefs.insert(make_pair(DREF_Latitude, XPLMFindDataRef("sim/flightmodel/position/latitude")));
drefs.insert(make_pair(DREF_Longitude, XPLMFindDataRef("sim/flightmodel/position/longitude")));
drefs.insert(make_pair(DREF_AGL, XPLMFindDataRef("sim/flightmodel/position/y_agl")));
drefs.insert(make_pair(DREF_Elevation, XPLMFindDataRef("sim/flightmodel/position/elevation")));
drefs.insert(make_pair(DREF_Elevation, XPLMFindDataRef("sim/flightmodel/position/elevation")));
drefs.insert(make_pair(DREF_LocalX, XPLMFindDataRef("sim/flightmodel/position/local_x")));
drefs.insert(make_pair(DREF_LocalY, XPLMFindDataRef("sim/flightmodel/position/local_y")));
@@ -522,7 +522,7 @@ namespace XPC
Log::FormatLine(LOG_ERROR, "DMAN", "ERROR: invalid DREF %s", dref.c_str());
return;
}
if (isnan(values[0]))
if (std::isnan(values[0]))
{
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Value must be a number (NaN received)");
return;
@@ -629,11 +629,12 @@ namespace XPC
if ((gear < -8.5 && gear > -9.5) || IsDefault(gear))
{
Log::WriteLine(LOG_INFO, "DMAN", "Not actually setting gear because of default value");
return;
}
if (isnan(gear) || gear < 0 || gear > 1)
if (std::isnan(gear) || gear < 0 || gear > 1)
{
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Gear value must be 0 or 1");
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Gear value must be between 0 and 1");
return;
}
@@ -657,11 +658,11 @@ namespace XPC
}
}
void DataManager::SetPosition(float pos[3], char aircraft)
void DataManager::SetPosition(double pos[3], char aircraft)
{
Log::FormatLine(LOG_INFO, "DMAN", "Setting position (%f, %f, %f) for aircraft %i",
pos[0], pos[1], pos[2], aircraft);
if (isnan(pos[0] + pos[1] + pos[2]))
if (std::isnan(pos[0] + pos[1] + pos[2]))
{
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Position must be a number (NaN received)");
return;
@@ -669,28 +670,28 @@ namespace XPC
if (IsDefault(pos[0]))
{
pos[0] = (float)GetDouble(DREF_Latitude, aircraft);
pos[0] = GetDouble(DREF_Latitude, aircraft);
}
if (IsDefault(pos[1]))
{
pos[1] = (float)GetDouble(DREF_Longitude, aircraft);
pos[1] = GetDouble(DREF_Longitude, aircraft);
}
if (IsDefault(pos[2]))
{
pos[2] = (float)GetDouble(DREF_Elevation, aircraft);
pos[2] = GetDouble(DREF_Elevation, aircraft);
}
// See: http://www.xsquawkbox.net/xpsdk/mediawiki/MovingThePlane
// Need to get the aircraft's current orientation before moving and
// reset the orientation after moving to update the quaternion
float orient[3];
orient[0] = GetFloat(DREF_Pitch, aircraft);
orient[1] = GetFloat(DREF_Roll, aircraft);
orient[2] = GetFloat(DREF_HeadingTrue, aircraft);
// See: http://www.xsquawkbox.net/xpsdk/mediawiki/MovingThePlane
// Need to get the aircraft's current orientation before moving and
// reset the orientation after moving to update the quaternion
float orient[3];
orient[0] = GetFloat(DREF_Pitch, aircraft);
orient[1] = GetFloat(DREF_Roll, aircraft);
orient[2] = GetFloat(DREF_HeadingTrue, aircraft);
// Now set the aircraft's position. Need to set world position for
// "long" moves, but since there isn't an easy way to calculate "long",
// we just set it every time.
// Now set the aircraft's position. Need to set world position for
// "long" moves, but since there isn't an easy way to calculate "long",
// we just set it every time.
double local[3];
XPLMWorldToLocal(pos[0], pos[1], pos[2], &local[0], &local[1], &local[2]);
// If the sim is paused, setting global position won't update the
@@ -699,19 +700,19 @@ namespace XPC
Set(DREF_LocalY, local[1], aircraft);
Set(DREF_LocalZ, local[2], aircraft);
// If the sim is unpaused, this will override the above settings.
Set(DREF_Latitude, (double)pos[0], aircraft);
Set(DREF_Longitude, (double)pos[1], aircraft);
Set(DREF_Elevation, (double)pos[2], aircraft);
Set(DREF_Latitude, pos[0], aircraft);
Set(DREF_Longitude, pos[1], aircraft);
Set(DREF_Elevation, pos[2], aircraft);
// Now reset orientation to update q
SetOrientation(orient, aircraft);
// Now reset orientation to update q
SetOrientation(orient, aircraft);
}
void DataManager::SetOrientation(float orient[3], char aircraft)
{
Log::FormatLine(LOG_INFO, "DMAN", "Setting orientation (%f, %f, %f) for aircraft %i",
orient[0], orient[1], orient[2], aircraft);
if (isnan(orient[0] + orient[1] + orient[2]))
if (std::isnan(orient[0] + orient[1] + orient[2]))
{
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Orientation must be a number (NaN received)");
return;
@@ -762,7 +763,7 @@ namespace XPC
{
Log::FormatLine(LOG_INFO, "DMAN", "Setting flaps (value:%f)", value);
if (isnan(value))
if (std::isnan(value))
{
Log::WriteLine(LOG_ERROR, "DMAN", "ERROR: Flap value must be a number (NaN received)");
return;
@@ -784,7 +785,7 @@ namespace XPC
return -998.0F;
}
bool DataManager::IsDefault(float value)
bool DataManager::IsDefault(double value)
{
return value < -997.9 && value > -999.1;
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_DATAMANAGER_H_
#define XPCPLUGIN_DATAMANAGER_H_
@@ -396,7 +396,7 @@ namespace XPC
/// \param pos An array containing latitude, longitude and altitude in
/// fractional degrees and meters above sea level.
/// \param aircraft The aircraft to set the position of.
static void SetPosition(float pos[3], char aircraft = 0);
static void SetPosition(double pos[3], char aircraft = 0);
/// Sets the orientation of the specified aircraft.
///
@@ -417,7 +417,7 @@ namespace XPC
///
/// \param value The value to check.
/// \returns true if value is a default value; otherwise false.
static bool IsDefault(float value);
static bool IsDefault(double value);
};
}
#endif

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
//
// X-Plane API
@@ -173,7 +173,7 @@ namespace XPC
glBegin(GL_LINE_STRIP);
for (size_t i = 0; i < numWaypoints; ++i)
{
LocalPoint* l = &localPoints[i];
LocalPoint* l = &localPoints[i];
glVertex3f((float)l->x, (float)l->y, (float)l->z);
}
glEnd();
@@ -226,7 +226,7 @@ namespace XPC
// Enable drawing if necessary
if (!msgEnabled)
{
XPLMRegisterDrawCallback(MessageDrawCallback, xplm_Phase_Window, 0, NULL);
XPLMRegisterDrawCallback(MessageDrawCallback, xplm_Phase_Window, 0, NULL);
msgEnabled = true;
}
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_DRAWING_H_
#define XPCPLUGIN_DRAWING_H_

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#include "Log.h"
@@ -111,7 +111,7 @@ namespace XPC
std::fprintf(fd, "X-Plane Connect [Version %s]\n", version.c_str());
std::fprintf(fd, "Compiled %s %s\n", __DATE__, __TIME__);
std::fprintf(fd, "Copyright (c) 2013-2017 United States Government as represented by the\n");
std::fprintf(fd, "Copyright (c) 2013-2018 United States Government as represented by the\n");
std::fprintf(fd, "Administrator of the National Aeronautics and Space Administration.\n");
std::fprintf(fd, "All Rights Reserved.\n\n");

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_LOG_H_
#define XPCPLUGIN_LOG_H_
@@ -27,7 +27,7 @@
namespace XPC
{
/// Handles logging for the plugin.
///
///
/// \details Provides functions to write lines to the XPC log file.
/// \author Jason Watkins
/// \version 1.1

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#include "Message.h"
#include "Log.h"
@@ -11,7 +11,7 @@
namespace XPC
{
Message::Message() {}
Message::Message() {}
Message Message::ReadFrom(const UDPSocket& sock)
{
@@ -110,17 +110,17 @@ namespace XPC
else if (head == "DREF")
{
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
string dref((char*)buffer + 6, buffer[5]);
Log::FormatLine(LOG_DEBUG, "DBUG", " DREF (size %i) = %s", dref.length(), dref.c_str());
ss.str("");
int values = buffer[6 + buffer[5]];
ss << " Values(size " << values << ") =";
for (int i = 0; i < values; ++i)
{
ss << " " << *((float*)(buffer + values + 1 + sizeof(float) * i));
string dref((char*)buffer + 6, buffer[5]);
Log::FormatLine(LOG_DEBUG, "DBUG", " DREF (size %i) = %s", dref.length(), dref.c_str());
ss.str("");
int values = buffer[6 + buffer[5]];
ss << " Values(size " << values << ") =";
for (int i = 0; i < values; ++i)
{
ss << " " << *((float*)(buffer + values + 1 + sizeof(float) * i));
}
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
}
else if (head == "GETC" || head == "GETP")
{
ss << " Aircraft:" << (int)buffer[5];
@@ -129,15 +129,15 @@ namespace XPC
else if (head == "GETD")
{
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
int cur = 6;
for (int i = 0; i < buffer[5]; ++i)
{
string dref((char*)buffer + cur + 1, buffer[cur]);
Log::FormatLine(LOG_DEBUG, "DBUG", " #%i/%i (size:%i) %s",
int cur = 6;
for (int i = 0; i < buffer[5]; ++i)
{
string dref((char*)buffer + cur + 1, buffer[cur]);
Log::FormatLine(LOG_DEBUG, "DBUG", " #%i/%i (size:%i) %s",
i + 1, buffer[5], dref.length(), dref.c_str());
cur += 1 + buffer[cur];
}
}
cur += 1 + buffer[cur];
}
}
else if (head == "POSI")
{
char aircraft = buffer[5];
@@ -146,14 +146,14 @@ namespace XPC
float orient[3];
memcpy(pos, buffer + 6, 12);
memcpy(orient, buffer + 18, 12);
ss << " AC:" << (int)aircraft;
ss << " AC:" << (int)aircraft;
ss << " Pos:(" << pos[0] << ' ' << pos[1] << ' ' << pos[2] << ") Orient:(";
ss << orient[3] << ' ' << orient[4] << ' ' << orient[5] << ") Gear:";
ss << orient[0] << ' ' << orient[1] << ' ' << orient[2] << ") Gear:";
ss << gear;
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
}
else if (head == "SIMU")
{
{
ss << ' ' << (int)buffer[5];
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
@@ -163,9 +163,9 @@ namespace XPC
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
else
{
{
ss << " UNKNOWN HEADER ";
Log::WriteLine(LOG_DEBUG, "DBUG", ss.str());
}
}
}
}

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_MESSAGE_H_
#define XPCPLUGIN_MESSAGE_H_

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
//
// X-Plane API
@@ -20,9 +20,16 @@
#include "Log.h"
#include "XPLMUtilities.h"
#include "XPLMGraphics.h"
#include <cmath>
#include <cstring>
#include <cstdint>
#define MULTICAST_GROUP "239.255.1.1"
#define MULITCAST_PORT 49710
namespace XPC
{
@@ -32,6 +39,8 @@ namespace XPC
std::string MessageHandlers::connectionKey;
MessageHandlers::ConnectionInfo MessageHandlers::connection;
UDPSocket* MessageHandlers::sock;
static sockaddr multicast_address = UDPSocket::GetAddr(MULTICAST_GROUP, MULITCAST_PORT);
void MessageHandlers::SetSocket(UDPSocket* socket)
{
@@ -127,6 +136,28 @@ namespace XPC
MessageHandlers::HandleUnknown(msg);
}
}
void MessageHandlers::SendBeacon(const std::string& pluginVersion, unsigned short pluginReceivePort, int xplaneVersion) {
unsigned char response[128] = "BECN";
std::size_t cur = 5;
// 2 bytes plugin port
*((uint16_t *)(response + cur)) = pluginReceivePort;
cur += sizeof(uint16_t);
// 4 bytes xplane version
*((uint32_t*)(response + cur)) = xplaneVersion;
cur += sizeof(uint32_t);
// plugin version
int len = pluginVersion.length();
memcpy(response + cur, pluginVersion.c_str(), len);
cur += strlen(pluginVersion.c_str()) + len;
sock->SendTo(response, cur, &multicast_address);
}
void MessageHandlers::HandleConn(const Message& msg)
{
@@ -342,10 +373,11 @@ namespace XPC
}
case 20: // Position
{
float pos[3];
pos[0] = values[i][2];
pos[1] = values[i][3];
pos[2] = values[i][4];
// TODO: loss of precision here
double pos[3];
pos[0] = (double)values[i][2];
pos[1] = (double)values[i][3];
pos[2] = (double)values[i][4];
DataManager::SetPosition(pos);
break;
}
@@ -439,7 +471,7 @@ namespace XPC
unsigned char aircraft = buffer[5];
// TODO(jason-watkins): Get proper printf specifier for unsigned char
Log::FormatLine(LOG_TRACE, "GCTL", "Getting control information for aircraft %u", aircraft);
float throttle[8];
unsigned char response[31] = "CTRL";
*((float*)(response + 5)) = DataManager::GetFloat(DREF_Elevator, aircraft);
@@ -524,13 +556,14 @@ namespace XPC
unsigned char response[34] = "POSI";
response[5] = (char)DataManager::GetInt(DREF_GearHandle, aircraft);
// TODO change lat/lon/h to double?
*((float*)(response + 6)) = (float)DataManager::GetDouble(DREF_Latitude, aircraft);
*((float*)(response + 10)) = (float)DataManager::GetDouble(DREF_Longitude, aircraft);
*((float*)(response + 14)) = (float)DataManager::GetDouble(DREF_Elevation, aircraft);
*((float*)(response + 18)) = DataManager::GetFloat(DREF_Pitch, aircraft);
*((float*)(response + 22)) = DataManager::GetFloat(DREF_Roll, aircraft);
*((float*)(response + 26)) = DataManager::GetFloat(DREF_HeadingTrue, aircraft);
float gear[10];
DataManager::GetFloatArray(DREF_GearDeploy, gear, 10, aircraft);
*((float*)(response + 30)) = gear[0];
@@ -545,18 +578,37 @@ namespace XPC
const unsigned char* buffer = msg.GetBuffer();
const std::size_t size = msg.GetSize();
if (size < 34)
char aircraftNumber = buffer[5];
float gear = *((float*)(buffer + 42));
double posd[3];
float orient[3];
if (size == 34) /* lat/lon/h as 32-bit float */
{
Log::FormatLine(LOG_ERROR, "POSI", "ERROR: Unexpected size: %i (Expected at least 34)", size);
posd[0] = *((float*)&buffer[6]);
posd[1] = *((float*)&buffer[10]);
posd[2] = *((float*)&buffer[14]);
memcpy(orient, buffer + 18, 12);
}
else if (size == 46) /* lat/lon/h as 64-bit double */
{
memcpy(posd, buffer + 6, 3*8);
memcpy(orient, buffer + 30, 12);
}
else
{
Log::FormatLine(LOG_ERROR, "POSI", "ERROR: Unexpected size: %i (Expected 34 or 46)", size);
return;
}
char aircraftNumber = buffer[5];
float gear = *((float*)(buffer + 30));
float pos[3];
float orient[3];
memcpy(pos, buffer + 6, 12);
memcpy(orient, buffer + 18, 12);
/* convert float to double */
DataManager::SetPosition(posd, aircraftNumber);
DataManager::SetOrientation(orient, aircraftNumber);
if (gear >= 0)
{
DataManager::SetGear(gear, true, aircraftNumber);
}
if (aircraftNumber > 0)
{
@@ -569,13 +621,6 @@ namespace XPC
DataManager::Set(DREF_PauseAI, ai, 0, 20);
}
}
DataManager::SetPosition(pos, aircraftNumber);
DataManager::SetOrientation(orient, aircraftNumber);
if (gear != -1)
{
DataManager::SetGear(gear, true, aircraftNumber);
}
}
void MessageHandlers::HandleSimu(const Message& msg)
@@ -583,13 +628,13 @@ namespace XPC
// Update log
Log::FormatLine(LOG_TRACE, "SIMU", "Message Received (Conn %i)", connection.id);
char v = msg.GetBuffer()[5];
if (v < 0 || v > 2)
unsigned char v = msg.GetBuffer()[5];
if (v < 0 || (v > 2 && v < 100) || (v > 119 && v < 200) || v > 219)
{
Log::FormatLine(LOG_ERROR, "SIMU", "ERROR: Invalid argument: %i", v);
return;
}
int value[20];
if (v == 2)
{
@@ -599,6 +644,16 @@ namespace XPC
value[i] = value[i] ? 0 : 1;
}
}
else if ((v >= 100) && (v < 120))
{
DataManager::GetIntArray(DREF_Pause, value, 20);
value[v - 100] = 1;
}
else if ((v >= 200) && (v < 220))
{
DataManager::GetIntArray(DREF_Pause, value, 20);
value[v - 200] = 0;
}
else
{
for (int i = 0; i < 20; ++i)
@@ -610,18 +665,27 @@ namespace XPC
// Set DREF
DataManager::Set(DREF_Pause, value, 20);
switch (v)
if (v == 0)
{
case 0:
Log::WriteLine(LOG_INFO, "SIMU", "Simulation resumed");
break;
case 1:
Log::WriteLine(LOG_INFO, "SIMU", "Simulation paused");
break;
case 2:
Log::FormatLine(LOG_INFO, "SIMU", "Simulation switched to %i", value[0]);
break;
Log::WriteLine(LOG_INFO, "SIMU", "Simulation resumed for all a/c");
}
else if (v == 1)
{
Log::WriteLine(LOG_INFO, "SIMU", "Simulation paused for all a/c");
}
else if (v == 2)
{
Log::FormatLine(LOG_INFO, "SIMU", "Simulation switched to %i for all a/c", value[0]);
}
else if ((v >= 100) && (v < 120))
{
Log::FormatLine(LOG_INFO, "SIMU", "Simulation paused for a/c %i", (v-100));
}
else if ((v >= 200) && (v < 220))
{
Log::FormatLine(LOG_INFO, "SIMU", "Simulation resumed for a/c %i", (v-100));
}
}
void MessageHandlers::HandleText(const Message& msg)
@@ -653,21 +717,111 @@ namespace XPC
Log::WriteLine(LOG_INFO, "TEXT", "[TEXT] Text set");
}
}
void MessageHandlers::HandleView(const Message& msg)
{
// Update Log
Log::FormatLine(LOG_TRACE, "VIEW", "Message Received(Conn %i)", connection.id);
int enable_camera_location = 0;
const std::size_t size = msg.GetSize();
if (size != 9)
if (size == 9)
{
Log::FormatLine(LOG_ERROR, "VIEW", "Error: Unexpected length. Message was %d bytes, expected 9.", size);
// default view switcher as before
}
else if (size == 37)
{
// Allow camera location control
enable_camera_location = 1;
}
else
{
Log::FormatLine(LOG_ERROR, "VIEW", "Error: Unexpected length. Message was %d bytes, expected 9 or 37.", size);
return;
}
const unsigned char* buffer = msg.GetBuffer();
int type = *((int*)(buffer + 5));
XPLMCommandKeyStroke(type);
if(type == 79 && enable_camera_location == 1) // runway camera view
{
static struct CameraProperties campos;
campos.loc[0] = *(double*)(buffer+9);
campos.loc[1] = *(double*)(buffer+17);
campos.loc[2] = *(double*)(buffer+25);
campos.direction[0] = -998;
campos.direction[1] = -998;
campos.direction[2] = -998;
campos.zoom = *(float*)(buffer+33);
Log::FormatLine(LOG_TRACE, "VIEW", "Cam pos %f %f %f zoom %f", campos.loc[0], campos.loc[1], campos.loc[2],campos.zoom);
XPLMControlCamera(xplm_ControlCameraUntilViewChanges, CamFunc, &campos);
}
}
int MessageHandlers::CamFunc( XPLMCameraPosition_t * outCameraPosition, int inIsLosingControl, void *inRefcon)
{
if (outCameraPosition && !inIsLosingControl)
{
struct CameraProperties* campos = (struct CameraProperties*)inRefcon;
// camera position
double clat = campos->loc[0];
double clon = campos->loc[1];
double calt = campos->loc[2];
double cX, cY, cZ;
XPLMWorldToLocal(clat, clon, calt, &cX, &cY, &cZ);
outCameraPosition->x = cX;
outCameraPosition->y = cY;
outCameraPosition->z = cZ;
// Log::FormatLine(LOG_TRACE, "CAM", "Cam pos %f %f %f", clat, clon, calt);
if(campos->direction[0] == -998) // calculate camera direction
{
// aircraft position
double x = XPC::DataManager::GetDouble(XPC::DREF_LocalX, 0);
double y = XPC::DataManager::GetDouble(XPC::DREF_LocalY, 0);
double z = XPC::DataManager::GetDouble(XPC::DREF_LocalZ, 0);
// relative position vector cam to plane
double dx = x - cX;
double dy = y - cY;
double dz = z - cZ;
// Log::FormatLine(LOG_TRACE, "CAM", "Cam vect %f %f %f", dx, dy, dz);
double pi = 3.141592653589793;
// horizontal distance
double dist = sqrt(dx*dx + dz*dz);
outCameraPosition->pitch = atan2(dy, dist) * 180.0/pi;
double angle = atan2(dz, dx) * 180.0/pi; // rel to pos right (pos X)
outCameraPosition->heading = 90 + angle; // rel to north
// Log::FormatLine(LOG_TRACE, "CAM", "Cam p %f hdg %f ", outCameraPosition->pitch, outCameraPosition->heading);
outCameraPosition->roll = 0;
}
else
{
outCameraPosition->roll = campos->direction[0];
outCameraPosition->pitch = campos->direction[1];
outCameraPosition->heading = campos->direction[2];
}
outCameraPosition->zoom = campos->zoom;
}
return 1;
}
void MessageHandlers::HandleWypt(const Message& msg)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_MESSAGEHANDLERS_H_
#define XPCPLUGIN_MESSAGEHANDLERS_H_
@@ -7,6 +7,9 @@
#include <string>
#include <map>
#include "XPLMCamera.h"
namespace XPC
{
/// A function that handles a message.
@@ -26,15 +29,17 @@ namespace XPC
/// socket.
///
/// \details After a message is read, HandleMessage analyzes the sender's network address
/// to determine whether the sender is a new client. It then either loads
/// connection details for an existing client, or creates a new connection record
/// for new clients. Finally, the message handler checks the message type and
/// dispatches the message to the appropriate handler.
/// to determine whether the sender is a new client. It then either loads
/// connection details for an existing client, or creates a new connection record
/// for new clients. Finally, the message handler checks the message type and
/// dispatches the message to the appropriate handler.
/// \param msg The message to be processed.
static void HandleMessage(Message& msg);
/// Sets the socket that message handlers use to send responses.
static void SetSocket(UDPSocket* socket);
static void SendBeacon(const std::string& pluginVersion, unsigned short pluginReceivePort, int xplaneVersion);
private:
// One handler per message type. Message types are descripbed on the
@@ -54,6 +59,14 @@ namespace XPC
static void HandleXPlaneData(const Message& msg);
static void HandleUnknown(const Message& msg);
static int CamFunc( XPLMCameraPosition_t * outCameraPosition, int inIsLosingControl, void *inRefcon);
struct CameraProperties{
double loc[3];
float direction[3];
float zoom;
};
typedef struct
{

View File

@@ -42,7 +42,7 @@ void XPCBroadcaster::RemoveListener(
}
void XPCBroadcaster::BroadcastMessage(
long inMessage,
int inMessage,
void * inParam)
{
ListenerVector::iterator iter;

View File

@@ -20,7 +20,7 @@ public:
protected:
void BroadcastMessage(
long inMessage,
int inMessage,
void * inParam=0);
private:

View File

@@ -14,7 +14,7 @@ public:
virtual ~XPCListener();
virtual void ListenToMessage(
long inMessage,
int inMessage,
void * inParam)=0;
private:

View File

@@ -21,7 +21,7 @@ void XPCProcess::StartProcessTime(float inSeconds)
FlightLoopCB, mCallbackTime, 1/*relative to now*/, reinterpret_cast<void *>(this));
}
void XPCProcess::StartProcessCycles(long inCycles)
void XPCProcess::StartProcessCycles(int inCycles)
{
mCallbackTime = -inCycles;
if (!mInCallback)

View File

@@ -10,7 +10,7 @@ public:
virtual ~XPCProcess();
void StartProcessTime(float inSeconds);
void StartProcessCycles(long inCycles);
void StartProcessCycles(int inCycles);
void StopProcess(void);
virtual void DoProcessing(

View File

@@ -22,7 +22,7 @@ XPCWidget::XPCWidget(
inIsRoot ? NULL : inParent,
inClass);
XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<long>(this));
XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<intptr_t>(this));
XPAddWidgetCallback(mWidget, WidgetCallback);
}
@@ -33,7 +33,7 @@ XPCWidget::XPCWidget(
mOwnsChildren(false),
mOwnsWidget(inOwnsWidget)
{
XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<long>(this));
XPSetWidgetProperty(mWidget, xpProperty_Object, reinterpret_cast<intptr_t>(this));
XPAddWidgetCallback(mWidget, WidgetCallback);
}
@@ -95,8 +95,8 @@ void XPCWidget::RemoveAttachment(
int XPCWidget::HandleWidgetMessage(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
return 0;
}
@@ -104,8 +104,8 @@ int XPCWidget::HandleWidgetMessage(
int XPCWidget::WidgetCallback(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
XPCWidget * me = reinterpret_cast<XPCWidget *>(XPGetWidgetProperty(inWidget, xpProperty_Object, NULL));
if (me == NULL)

View File

@@ -14,8 +14,8 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)=0;
intptr_t inParam1,
intptr_t inParam2)=0;
};
@@ -56,16 +56,16 @@ public:
virtual int HandleWidgetMessage(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
static int WidgetCallback(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
typedef std::pair<XPCWidgetAttachment *, bool> AttachmentInfo;
typedef std::vector<AttachmentInfo> AttachmentVector;

View File

@@ -22,8 +22,8 @@ int XPCKeyFilterAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if (inMessage == xpMsg_KeyPress)
{
@@ -42,7 +42,7 @@ int XPCKeyFilterAttachment::HandleWidgetMessage(
XPCKeyMessageAttachment::XPCKeyMessageAttachment(
char inKey,
long inMessage,
int inMessage,
void * inParam,
bool inConsume,
bool inVkey,
@@ -62,8 +62,8 @@ int XPCKeyMessageAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if (inMessage == xpMsg_KeyPress)
{
@@ -81,7 +81,7 @@ int XPCKeyMessageAttachment::HandleWidgetMessage(
XPCPushButtonMessageAttachment::XPCPushButtonMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener) :
mMsg(inMessage), mParam(inParam), mWidget(inWidget)
@@ -98,8 +98,8 @@ int XPCPushButtonMessageAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if ((inMessage == xpMsg_PushButtonPressed) && ((XPWidgetID) inParam1 == mWidget))
{
@@ -117,7 +117,7 @@ int XPCPushButtonMessageAttachment::HandleWidgetMessage(
XPCSliderMessageAttachment::XPCSliderMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener) :
mMsg(inMessage), mParam(inParam), mWidget(inWidget)
@@ -134,8 +134,8 @@ int XPCSliderMessageAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if ((inMessage == xpMsg_ScrollBarSliderPositionChanged) && ((XPWidgetID) inParam1 == mWidget))
{
@@ -149,7 +149,7 @@ int XPCSliderMessageAttachment::HandleWidgetMessage(
XPCCloseButtonMessageAttachment::XPCCloseButtonMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener) :
mMsg(inMessage), mParam(inParam), mWidget(inWidget)
@@ -166,8 +166,8 @@ int XPCCloseButtonMessageAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if ((inMessage == xpMessage_CloseButtonPushed) && ((XPWidgetID) inParam1 == mWidget))
{
@@ -190,8 +190,8 @@ int XPCTabGroupAttachment::HandleWidgetMessage(
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2)
intptr_t inParam1,
intptr_t inParam2)
{
if ((inMessage == xpMsg_KeyPress) && (KEY_CHAR(inParam1) == XPLM_KEY_TAB) &&
((KEY_FLAGS(inParam1) & xplm_UpFlag) == 0))
@@ -199,7 +199,7 @@ int XPCTabGroupAttachment::HandleWidgetMessage(
bool backwards = (KEY_FLAGS(inParam1) & xplm_ShiftFlag) != 0;
std::vector<XPWidgetID> widgets;
XPCGetOrderedSubWidgets(inWidget, widgets);
long n, index = 0;
int n, index = 0;
XPWidgetID focusWidget = XPGetWidgetWithFocus();
std::vector<XPWidgetID>::iterator iter = std::find(widgets.begin(), widgets.end(), focusWidget);
if (iter != widgets.end())
@@ -254,8 +254,8 @@ static void XPCGetOrderedSubWidgets(
std::vector<XPWidgetID>& outChildren)
{
outChildren.clear();
long count = XPCountChildWidgets(inWidget);
for (long n = 0; n < count; ++n)
int count = XPCountChildWidgets(inWidget);
for (int n = 0; n < count; ++n)
{
XPWidgetID child = XPGetNthChildWidget(inWidget, n);
outChildren.push_back(child);

View File

@@ -18,8 +18,8 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
@@ -34,7 +34,7 @@ public:
XPCKeyMessageAttachment(
char inKey,
long inMessage,
int inMessage,
void * inParam,
bool inConsume,
bool inVkey,
@@ -45,14 +45,14 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
char mKey;
bool mVkey;
long mMsg;
int mMsg;
void * mParam;
bool mConsume;
@@ -63,7 +63,7 @@ public:
XPCPushButtonMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener);
virtual ~XPCPushButtonMessageAttachment();
@@ -72,12 +72,12 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
XPWidgetID mWidget;
long mMsg;
int mMsg;
void * mParam;
};
@@ -86,7 +86,7 @@ public:
XPCSliderMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener);
virtual ~XPCSliderMessageAttachment();
@@ -95,12 +95,12 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
XPWidgetID mWidget;
long mMsg;
int mMsg;
void * mParam;
};
@@ -110,7 +110,7 @@ public:
XPCCloseButtonMessageAttachment(
XPWidgetID inWidget,
long inMessage,
int inMessage,
void * inParam,
XPCListener * inListener);
virtual ~XPCCloseButtonMessageAttachment();
@@ -119,12 +119,12 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
private:
XPWidgetID mWidget;
long mMsg;
int mMsg;
void * mParam;
};
@@ -138,8 +138,8 @@ public:
XPCWidget * inObject,
XPWidgetMessage inMessage,
XPWidgetID inWidget,
long inParam1,
long inParam2);
intptr_t inParam1,
intptr_t inParam2);
};

View File

@@ -27,7 +27,7 @@
extern "C" {
#endif
#ifdef _WIN32
#if IBM
#include <windows.h>
#else
#include <stdint.h>
@@ -49,7 +49,7 @@ extern "C" {
#ifdef __cplusplus
#ifdef APL
#if APL
#if __GNUC__ >= 4
#define PLUGIN_API extern "C" __attribute__((visibility("default")))
#elif __MACH__
@@ -57,16 +57,16 @@ extern "C" {
#else
#define PLUGIN_API extern "C" __declspec(dllexport)
#endif
#endif
#ifdef _WIN32
#elif IBM
#define PLUGIN_API extern "C" __declspec(dllexport)
#endif
#ifdef LIN
#elif LIN
#if __GNUC__ >= 4
#define PLUGIN_API extern "C" __attribute__((visibility("default")))
#else
#define PLUGIN_API extern "C"
#endif
#else
#error "Platform not defined!"
#endif
#else
#if APL
@@ -90,7 +90,7 @@ extern "C" {
#endif
#endif
#ifdef APL
#if APL
#if XPLM
#if __GNUC__ >= 4
#define XPLM_API __attribute__((visibility("default")))
@@ -102,15 +102,13 @@ extern "C" {
#else
#define XPLM_API
#endif
#endif
#ifdef _WIN32
#elif IBM
#if XPLM
#define XPLM_API __declspec(dllexport)
#else
#define XPLM_API __declspec(dllimport)
#endif
#endif
#ifdef LIN
#elif LIN
#if XPLM
#if __GNUC__ >= 4
#define XPLM_API __attribute__((visibility("default")))
@@ -120,6 +118,8 @@ extern "C" {
#else
#define XPLM_API
#endif
#else
#error "Platform not defined!"
#endif
/***************************************************************************

View File

@@ -51,6 +51,11 @@ Mach-O if you want to use 2.0 features.
This section contains per-release notes for the history of the X-Plane SDK.
X-Plane SDK Release 2.1.3 11/14/13
Fixed XPC Wrappers to use int and intptr_t instead of long. This fixes
crashes for plugins on 64-bit Windows.
X-Plane SDK Release 2.1.2 RC2 1/15/13
Removed headers from frameworks, as they don't work; updated README.

27
xpcPlugin/Timer.cpp Normal file
View File

@@ -0,0 +1,27 @@
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#include "Timer.h"
using namespace std;
namespace XPC {
void Timer::start(const chrono::milliseconds interval, const Callback &callback) {
{
running.test_and_set();
th = thread([=]()
{
while (running.test_and_set()) {
this_thread::sleep_for(interval);
callback();
}
});
}
}
void Timer::stop() {
running.clear();
if(th.joinable()) {
th.join();
}
}
}

30
xpcPlugin/Timer.h Normal file
View File

@@ -0,0 +1,30 @@
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_TIMER_H_
#define XPCPLUGIN_TIMER_H_
#include <stdio.h>
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <functional>
namespace XPC {
class Timer
{
std::atomic_flag running;
std::thread th;
public:
using Callback = std::function<void(void)>;
void start(const std::chrono::milliseconds, const Callback &callback);
void stop();
};
}
#endif /* Timer_hpp */

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#include "Log.h"
#include "UDPSocket.h"
@@ -138,6 +138,18 @@ namespace XPC
Log::FormatLine(LOG_INFO, tag, "Send succeeded. (remote: %s)", GetHost(remote).c_str());
}
}
sockaddr UDPSocket::GetAddr(std::string address, unsigned short port)
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(address.c_str());
addr.sin_port = htons(port);
sockaddr* sa = reinterpret_cast<sockaddr*>(&addr);
return *sa;
}
std::string UDPSocket::GetHost(sockaddr* sa)
{

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
#ifndef XPCPLUGIN_SOCKET_H_
#define XPCPLUGIN_SOCKET_H_
@@ -56,12 +56,14 @@ namespace XPC
/// \param len The number of bytes to send.
/// \param remote The destination socket.
void SendTo(const unsigned char* buffer, std::size_t len, sockaddr* remote) const;
/// Gets a string containing the IP address and port contained in the given sockaddr.
///
/// \param addr The socket address to parse.
/// \returns A string representation of the socket address.
static std::string GetHost(sockaddr* addr);
static sockaddr GetAddr(std::string address, unsigned short port);
private:
#ifdef _WIN32
SOCKET sock;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2013-2017 United States Government as represented by the Administrator of the
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
// National Aeronautics and Space Administration. All Rights Reserved.
//
// DISCLAIMERS
@@ -60,12 +60,16 @@
#include "Log.h"
#include "MessageHandlers.h"
#include "UDPSocket.h"
#include "Timer.h"
// XPLM Includes
#include "XPLMProcessing.h"
#include "XPLMUtilities.h"
// System Includes
#include <cstdlib>
#include <cstring>
#include <cmath>
#ifdef __APPLE__
#include <mach/mach_time.h>
#endif
@@ -73,7 +77,12 @@
#define RECVPORT 49009 // Port that the plugin receives commands on
#define OPS_PER_CYCLE 20 // Max Number of operations per cycle
#define XPC_PLUGIN_VERSION "1.3-rc.1"
using namespace std;
XPC::UDPSocket* sock = NULL;
XPC::Timer* timer = NULL;
double start;
double lap;
@@ -89,12 +98,12 @@ static float XPCFlightLoopCallback(float inElapsedSinceLastCall, float inElapsed
PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc)
{
strcpy(outName, "X-Plane Connect [Version 1.2.1]");
strcpy(outName, "X-Plane Connect [Version 1.3-rc.1]");
strcpy(outSig, "NASA.XPlaneConnect");
strcpy(outDesc, "X Plane Communications Toolbox\nCopyright (c) 2013-2017 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved.");
strcpy(outDesc, "X Plane Communications Toolbox\nCopyright (c) 2013-2018 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved.");
#if (__APPLE__)
if ( abs(timeConvert) <= 1e-9 ) // is about 0
if ( timeConvert <= 1e-9 ) // is about 0
{
mach_timebase_info_data_t timeBase;
(void)mach_timebase_info(&timeBase);
@@ -103,7 +112,7 @@ PLUGIN_API int XPluginStart(char* outName, char* outSig, char* outDesc)
1000000000.0;
}
#endif
XPC::Log::Initialize("1.2.1");
XPC::Log::Initialize(XPC_PLUGIN_VERSION);
XPC::Log::WriteLine(LOG_INFO, "EXEC", "Plugin Start");
XPC::DataManager::Initialize();
@@ -131,12 +140,18 @@ PLUGIN_API void XPluginDisable(void)
XPC::Drawing::ClearWaypoints();
XPC::Log::WriteLine(LOG_INFO, "EXEC", "Plugin Disabled, sockets closed");
timer->stop();
delete timer;
timer = NULL;
}
PLUGIN_API int XPluginEnable(void)
{
// Open sockets
sock = new XPC::UDPSocket(RECVPORT);
timer = new XPC::Timer();
XPC::MessageHandlers::SetSocket(sock);
XPC::Log::WriteLine(LOG_INFO, "EXEC", "Plugin Enabled, sockets opened");
@@ -145,11 +160,20 @@ PLUGIN_API int XPluginEnable(void)
XPC::Log::FormatLine(LOG_INFO, "EXEC", "Benchmarking Enabled (Verbosity: %i)", benchmarkingSwitch);
}
XPC::Log::FormatLine(LOG_INFO, "EXEC", "Debug Logging Enabled (Verbosity: %i)", LOG_LEVEL);
float interval = -1; // Call every frame
void* refcon = NULL; // Don't pass anything to the callback directly
XPLMRegisterFlightLoopCallback(XPCFlightLoopCallback, interval, refcon);
int xpVer;
XPLMGetVersions(&xpVer, NULL, NULL);
timer->start(chrono::milliseconds(1000), [=]{
XPC::MessageHandlers::SendBeacon(XPC_PLUGIN_VERSION, RECVPORT, xpVer);
});
return 1;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
3D0F44CE21C6D3E7008A0655 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D0F44CD21C6D3E7008A0655 /* Timer.cpp */; };
BE37D960187C8B0F0033B082 /* XPCPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE37D95E187C8B0F0033B082 /* XPCPlugin.cpp */; };
BE8361EF18C5591C00E9C923 /* mac.xpl in CopyFiles */ = {isa = PBXBuildFile; fileRef = D607B19909A556E400699BC3 /* mac.xpl */; };
BEABAD371AE041A3007BA7DA /* DataManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BEABAD2B1AE041A3007BA7DA /* DataManager.cpp */; };
@@ -36,6 +37,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3D0F44CC21C6D3E7008A0655 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
3D0F44CD21C6D3E7008A0655 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
BE37D95E187C8B0F0033B082 /* XPCPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XPCPlugin.cpp; sourceTree = SOURCE_ROOT; usesTabs = 1; };
BEABAD2B1AE041A3007BA7DA /* DataManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataManager.cpp; sourceTree = "<group>"; };
BEABAD2C1AE041A3007BA7DA /* DataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataManager.h; sourceTree = "<group>"; };
@@ -76,6 +79,7 @@
AC4E46B809C2E0B3006B7E1B /* src */ = {
isa = PBXGroup;
children = (
3D0F44CD21C6D3E7008A0655 /* Timer.cpp */,
BE37D95E187C8B0F0033B082 /* XPCPlugin.cpp */,
BEDC620218EDF1A7005DB364 /* xplaneConnect.c */,
BEABAD2B1AE041A3007BA7DA /* DataManager.cpp */,
@@ -91,6 +95,7 @@
BE953E0B1AEB183400CE4A8C /* inc */ = {
isa = PBXGroup;
children = (
3D0F44CC21C6D3E7008A0655 /* Timer.h */,
BEDC620318EDF1A7005DB364 /* xplaneConnect.h */,
BEABAD2C1AE041A3007BA7DA /* DataManager.h */,
BEABAD301AE041A3007BA7DA /* Drawing.h */,
@@ -190,6 +195,7 @@
BEDC620418EDF1A7005DB364 /* xplaneConnect.c in Sources */,
BEABAD371AE041A3007BA7DA /* DataManager.cpp in Sources */,
BEABAD391AE041A3007BA7DA /* Drawing.cpp in Sources */,
3D0F44CE21C6D3E7008A0655 /* Timer.cpp in Sources */,
BE37D960187C8B0F0033B082 /* XPCPlugin.cpp in Sources */,
BEABAD3F1AE0498D007BA7DA /* UDPSocket.cpp in Sources */,
);
@@ -298,11 +304,14 @@
D607B19C09A556E400699BC3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD)";
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
CONFIGURATION_BUILD_DIR = ./XPlaneConnect/;
CURRENT_PROJECT_VERSION = 0.24;
GCC_ENABLE_OBJC_EXCEPTIONS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO;
@@ -337,11 +346,14 @@
D607B19D09A556E400699BC3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD)";
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_ENABLE_MODULES = YES;
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_WARN_CXX0X_EXTENSIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO;
CONFIGURATION_BUILD_DIR = ./XPlaneConnect/;
CURRENT_PROJECT_VERSION = 0.24;
GCC_ENABLE_OBJC_EXCEPTIONS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO;
@@ -365,9 +377,7 @@
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/xplaneConnect-asdjuezcjkhojuewbyxhyhabxfwc/Build/Products/Debug",
);
MACH_O_TYPE = mh_bundle;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_NAME = mac;
SDKROOT = macosx;
STRIP_INSTALLED_PRODUCT = YES;

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
# Visual Studio 2015
VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xpcPlugin", "xpcPlugin.vcxproj", "{6AEF5D28-2701-44FF-AE10-1DEF07C5CAEA}"
EndProject

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -28,25 +28,25 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -121,7 +121,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>EnableAllWarnings</WarningLevel>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>IBM=1;XPLM200;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -171,7 +171,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>EnableAllWarnings</WarningLevel>
<WarningLevel>Level3</WarningLevel>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>IBM=1;XPLM200;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>
@@ -206,6 +206,7 @@
<ClInclude Include="..\Log.h" />
<ClInclude Include="..\Message.h" />
<ClInclude Include="..\MessageHandlers.h" />
<ClCompile Include="..\Timer.h" />
<ClInclude Include="..\UDPSocket.h" />
</ItemGroup>
<ItemGroup>
@@ -214,6 +215,7 @@
<ClCompile Include="..\Log.cpp" />
<ClCompile Include="..\Message.cpp" />
<ClCompile Include="..\MessageHandlers.cpp" />
<ClCompile Include="..\Timer.cpp" />
<ClCompile Include="..\UDPSocket.cpp" />
<ClCompile Include="..\XPCPlugin.cpp" />
</ItemGroup>