Refactored various message-related operations into the Message class.
- Replaces the XPCMessage struct. - Messages are now read from a UDPSocket by the Message class. - Printing messages to the log is now handled by the Message class. - In the future, may extend this class with command-specific subclasses that encapsulate additional message parsing functionality.
This commit is contained in:
166
xpcPlugin/Message.cpp
Normal file
166
xpcPlugin/Message.cpp
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||||
|
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||||
|
#include "Message.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "xplaneConnect.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace XPC
|
||||||
|
{
|
||||||
|
Message::Message() {}
|
||||||
|
|
||||||
|
Message Message::ReadFrom(UDPSocket& sock)
|
||||||
|
{
|
||||||
|
Message m;
|
||||||
|
int len = sock.Read(m.buffer, bufferSize, &m.source);
|
||||||
|
m.size = len < 0 ? 0 : len;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t Message::GetMagicNumber()
|
||||||
|
{
|
||||||
|
if (size < 4)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return *((std::uint32_t*)buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Message::GetHead()
|
||||||
|
{
|
||||||
|
if (size < 4)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return std::string((char*)buffer, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::uint8_t* Message::GetBuffer()
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Message::GetSize()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr Message::GetSource()
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::PrintToLog()
|
||||||
|
{
|
||||||
|
#if LOG_VERBOSITY > 2
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "[DEBUG]";
|
||||||
|
|
||||||
|
// Dump raw bytes to string
|
||||||
|
ss << std::hex << std::setfill('0');
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
ss << ' ' << std::setw(2) << static_cast<unsigned>(buffer[i]);
|
||||||
|
}
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << "[" << GetHead() << "-DEBUG](" << buffer[4] << ")";
|
||||||
|
switch (GetMagicNumber())
|
||||||
|
{
|
||||||
|
case 0x434F4E4E: // CONN
|
||||||
|
case 0x57595054: // WYPT
|
||||||
|
case 0x54455854: // TEXT
|
||||||
|
{
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x4354524C: // CTRL
|
||||||
|
{
|
||||||
|
xpcCtrl ctrl = parseCTRL((char*)buffer);
|
||||||
|
ss << " (" << ctrl.pitch << " " << ctrl.roll << " " << ctrl.yaw << ") ";
|
||||||
|
ss << ctrl.throttle << " " << ctrl.gear << " " << ctrl.flaps;
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x44415441: // DATA
|
||||||
|
{
|
||||||
|
float dataRef[30][9];
|
||||||
|
short numCols = parseDATA((char*)buffer, size, dataRef);
|
||||||
|
ss << " (" << numCols << " lines)";
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
for (int i = 0; i < numCols; ++i)
|
||||||
|
{
|
||||||
|
ss.str("");
|
||||||
|
ss << "\t#" << dataRef[i][0];
|
||||||
|
for (int j = 1; j < 9; ++j)
|
||||||
|
{
|
||||||
|
ss << " " << dataRef[i][j];
|
||||||
|
}
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x44524546: // DREF
|
||||||
|
{
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
std::string dref((char*)buffer + 6, buffer[5]);
|
||||||
|
Log::FormatLine("-\tDREF (size %i) = %s", dref.length(), dref.c_str());
|
||||||
|
ss.str("");
|
||||||
|
int values = buffer[6 + buffer[5]];
|
||||||
|
ss << "\tValues(size " << values << ") =";
|
||||||
|
for (int i = 0; i < values; ++i)
|
||||||
|
{
|
||||||
|
ss << " " << *((float*)(buffer + values + 1 + sizeof(float) * i));
|
||||||
|
}
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x47455444: // GETD
|
||||||
|
{
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
int cur = 6;
|
||||||
|
for (int i = 0; i < buffer[5]; ++i)
|
||||||
|
{
|
||||||
|
std::string dref((char*)buffer + cur + 1, buffer[cur]);
|
||||||
|
Log::FormatLine("\t#%i/%i (size:%i) %s", i + 1, buffer[5], dref.length(), dref);
|
||||||
|
cur += 1 + buffer[cur];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x504F5349: // POSI
|
||||||
|
{
|
||||||
|
float position[6] = { 0.0 };
|
||||||
|
short aircraft = 0;
|
||||||
|
float gear = -1.0;
|
||||||
|
aircraft = parsePOSI((char*)buffer, position, 6, &gear);
|
||||||
|
ss << ' ' << aircraft;
|
||||||
|
ss << " (" << position[0] << ' ' << position[1] << ' ' << position[2] << ") (";
|
||||||
|
ss << position[3] << ' ' << position[4] << ' ' << position[5] << ") ";
|
||||||
|
ss << gear;
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x53494D55: // SIMU
|
||||||
|
{
|
||||||
|
ss << ' ' << buffer[5];
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
ss << " UNKNOWN HEADER";
|
||||||
|
Log::WriteLine(ss.str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
57
xpcPlugin/Message.h
Normal file
57
xpcPlugin/Message.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the
|
||||||
|
//National Aeronautics and Space Administration. All Rights Reserved.
|
||||||
|
#ifndef XPC_MESSAGE_H
|
||||||
|
#define XPC_MESSAGE_H
|
||||||
|
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
|
||||||
|
namespace XPC
|
||||||
|
{
|
||||||
|
/// Represents a message received from an XPC client.
|
||||||
|
///
|
||||||
|
/// \author Jason Watkins
|
||||||
|
/// \version 1.0
|
||||||
|
/// \since 1.0
|
||||||
|
/// \date Intial Version: 2015-04-11
|
||||||
|
/// \date Last Updated: 2015-04-11
|
||||||
|
class Message
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Reads a datagram from the specified socket and interprets it as a
|
||||||
|
/// message.
|
||||||
|
///
|
||||||
|
/// \param sock The socket to read from.
|
||||||
|
/// \returns A message parsed from the data read from sock. If no
|
||||||
|
/// data was read or an error occurs, returns a message
|
||||||
|
/// with the size set to 0.
|
||||||
|
static Message ReadFrom(UDPSocket& sock);
|
||||||
|
|
||||||
|
/// Gets the message header in binary form.
|
||||||
|
std::uint32_t GetMagicNumber();
|
||||||
|
|
||||||
|
/// Gets the message header.
|
||||||
|
std::string GetHead();
|
||||||
|
|
||||||
|
/// Gets the buffer underlying the message.
|
||||||
|
const std::uint8_t* GetBuffer();
|
||||||
|
|
||||||
|
/// Gets the size of the message in bytes.
|
||||||
|
std::size_t GetSize();
|
||||||
|
|
||||||
|
/// Gets the address this message was read from.
|
||||||
|
struct sockaddr GetSource();
|
||||||
|
|
||||||
|
/// Prints the contents of the message to the XPC log.
|
||||||
|
void PrintToLog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Message();
|
||||||
|
|
||||||
|
static const std::size_t bufferSize = 4096;
|
||||||
|
std::uint8_t buffer[bufferSize];
|
||||||
|
std::size_t size;
|
||||||
|
struct sockaddr source;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -63,6 +63,7 @@
|
|||||||
// XPC Includes
|
// XPC Includes
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Drawing.h"
|
#include "Drawing.h"
|
||||||
|
#include "Message.h"
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "xpcPluginTools.h"
|
#include "xpcPluginTools.h"
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ int handleDREF(char *buf);
|
|||||||
int handleVIEW();
|
int handleVIEW();
|
||||||
int handleDATA(char *buf, int buflen);
|
int handleDATA(char *buf, int buflen);
|
||||||
int handleTEXT(char *buf, int len);
|
int handleTEXT(char *buf, int len);
|
||||||
short handleInput(struct XPCMessage * theMessage);
|
short handleInput(XPC::Message& msg);
|
||||||
|
|
||||||
char setPOSI(short aircraft, float pos[3]);
|
char setPOSI(short aircraft, float pos[3]);
|
||||||
char setORIENT(short aircraft, float orient[3]);
|
char setORIENT(short aircraft, float orient[3]);
|
||||||
@@ -239,7 +240,6 @@ float MyFlightLoopCallback( float inElapsedSinceLastCall,
|
|||||||
#if (__APPLE__)
|
#if (__APPLE__)
|
||||||
double diff_t;
|
double diff_t;
|
||||||
#endif
|
#endif
|
||||||
XPCMessage theMessage;
|
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
if (benchmarkingSwitch > 1)
|
if (benchmarkingSwitch > 1)
|
||||||
@@ -255,8 +255,8 @@ float MyFlightLoopCallback( float inElapsedSinceLastCall,
|
|||||||
start = (double)mach_absolute_time( ) * timeConvert;
|
start = (double)mach_absolute_time( ) * timeConvert;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
readMessage(recvSocket, &theMessage);
|
XPC::Message msg = XPC::Message::ReadFrom(*recvSocket);
|
||||||
result = handleInput(&theMessage);
|
result = handleInput(msg);
|
||||||
|
|
||||||
if (benchmarkingSwitch > 0)
|
if (benchmarkingSwitch > 0)
|
||||||
{
|
{
|
||||||
@@ -282,145 +282,143 @@ float MyFlightLoopCallback( float inElapsedSinceLastCall,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
short handleInput(struct XPCMessage * theMessage)
|
short handleInput(XPC::Message& msg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char IP[16] = {0};
|
char IP[16] = { 0 };
|
||||||
unsigned short port = 0;
|
unsigned short port = 0;
|
||||||
|
|
||||||
current_connection = -1;
|
current_connection = -1;
|
||||||
|
|
||||||
if (theMessage->msglen > 0) // If message received
|
if (msg.GetSize() == 0)
|
||||||
{
|
{
|
||||||
if (LOG_VERBOSITY > 0)
|
// No message received
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.PrintToLog();
|
||||||
|
|
||||||
|
// Check for existing connection
|
||||||
|
port = getIP(msg.GetSource(), IP);
|
||||||
|
for (i = 0; i < number_of_connections; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(connectionList[i].IP, IP) == 0 && port == connectionList[i].fromPort && port > 0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
current_connection = i;
|
||||||
#else
|
break;
|
||||||
printBufferToLog(*theMessage);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Check for existing connection
|
|
||||||
port = getIP(theMessage->recvaddr,IP);
|
if (current_connection == -1) //SETUP NEW CONNECTION
|
||||||
for (i=0; i<number_of_connections; i++)
|
{
|
||||||
|
if (number_of_connections >= MAXCONN) // Handle hitting MAXCONN (COME UP WITH A BETTER SOLUTION)
|
||||||
{
|
{
|
||||||
if (strcmp(connectionList[i].IP,IP) == 0 && port == connectionList[i].fromPort && port > 0)
|
XPC::Log::WriteLine("[EXEC] Hit maximum number of connections-Removing old ones");
|
||||||
{
|
number_of_connections = 0;
|
||||||
current_connection=i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_connection == -1) //SETUP NEW CONNECTION
|
memcpy(connectionList[number_of_connections].IP, IP, 16);
|
||||||
{
|
connectionList[number_of_connections].recPort = 49008;
|
||||||
if (number_of_connections>=MAXCONN) // Handle hitting MAXCONN (COME UP WITH A BETTER SOLUTION)
|
connectionList[number_of_connections].fromPort = port;
|
||||||
{
|
current_connection = number_of_connections;
|
||||||
XPC::Log::WriteLine("[EXEC] Hit maximum number of connections-Removing old ones");
|
number_of_connections++;
|
||||||
number_of_connections = 0;
|
|
||||||
}
|
// Log Connection
|
||||||
|
XPC::Log::FormatLine("[EXEC] New Connection [%i]. IP=%s, port=%i", number_of_connections, IP, port);
|
||||||
memcpy(connectionList[number_of_connections].IP,IP,16);
|
}
|
||||||
connectionList[number_of_connections].recPort = 49008;
|
|
||||||
connectionList[number_of_connections].fromPort = port;
|
std::string head = msg.GetHead();
|
||||||
current_connection = number_of_connections;
|
if (head == "CONN") // Header = CONN (Connection)
|
||||||
number_of_connections ++;
|
{
|
||||||
|
handleCONN((char*)msg.GetBuffer());
|
||||||
// Log Connection
|
}
|
||||||
XPC::Log::FormatLine("[EXEC] New Connection [%i]. IP=%s, port=%i", number_of_connections, IP, port);
|
else if (head == "SIMU") // Header = SIMU
|
||||||
}
|
{
|
||||||
|
handleSIMU((char*)msg.GetBuffer());
|
||||||
if (strncmp(theMessage->head,"CONN",4)==0) // Header = CONN (Connection)
|
}
|
||||||
{
|
else if (head == "POSI") // Header = POSI (Position)
|
||||||
handleCONN(theMessage->msg);
|
{
|
||||||
}
|
handlePOSI((char*)msg.GetBuffer());
|
||||||
else if (strncmp(theMessage->head,"SIMU",4)==0) // Header = SIMU
|
}
|
||||||
{
|
else if (head == "CTRL") // Header = CTRL (Control)
|
||||||
handleSIMU(theMessage->msg);
|
{
|
||||||
}
|
handleCTRL((char*)msg.GetBuffer());
|
||||||
else if (strncmp(theMessage->head,"POSI",4)==0) // Header = POSI (Position)
|
}
|
||||||
{
|
else if (head == "WYPT") // Header = WYPT (Waypoint Draw)
|
||||||
handlePOSI(theMessage->msg);
|
{
|
||||||
}
|
handleWYPT((char*)msg.GetBuffer(), msg.GetSize());
|
||||||
else if (strncmp(theMessage->head,"CTRL",4)==0) // Header = CTRL (Control)
|
}
|
||||||
{
|
else if (head == "GETD") // Header = GETD (Data Request)
|
||||||
handleCTRL(theMessage->msg);
|
{
|
||||||
}
|
handleGETD((char*)msg.GetBuffer());
|
||||||
else if (strncmp(theMessage->head,"WYPT",4)==0) // Header = WYPT (Waypoint Draw)
|
}
|
||||||
{
|
else if (head == "DREF") // Header = DREF (By Data Ref) (this is slower than DATA)
|
||||||
handleWYPT(theMessage->msg, theMessage->msglen);
|
{
|
||||||
}
|
handleDREF((char*)msg.GetBuffer());
|
||||||
else if (strncmp(theMessage->head,"GETD",4)==0) // Header = GETD (Data Request)
|
}
|
||||||
{
|
else if (head == "VIEW") // Header = VIEW (Change View)
|
||||||
handleGETD(theMessage->msg);
|
{
|
||||||
}
|
handleVIEW();
|
||||||
else if (strncmp(theMessage->head,"DREF",4)==0) // Header = DREF (By Data Ref) (this is slower than DATA)
|
}
|
||||||
{
|
else if (head == "DATA") // Header = DATA (UDP Data)
|
||||||
handleDREF(theMessage->msg);
|
{
|
||||||
}
|
handleDATA((char*)msg.GetBuffer(), msg.GetSize());
|
||||||
else if (strncmp(theMessage->head,"VIEW",4)==0) // Header = VIEW (Change View)
|
}
|
||||||
{
|
else if (head == "TEXT") // Header = TEXT (Screen message)
|
||||||
handleVIEW();
|
{
|
||||||
}
|
handleTEXT((char*)msg.GetBuffer(), msg.GetSize());
|
||||||
else if (strncmp(theMessage->head,"DATA",4)==0) // Header = DATA (UDP Data)
|
}
|
||||||
{
|
else if ((head == "DSEL") || (head == "USEL")) // Header = DSEL/USEL (Select UDP Send)
|
||||||
handleDATA(theMessage->msg, theMessage->msglen);
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if (strncmp(theMessage->head, "TEXT", 4) == 0) // Header = TEXT (Screen message)
|
}
|
||||||
{
|
else if ((head == "DCOC") || (head == "UCOC"))
|
||||||
handleTEXT(theMessage->msg, theMessage->msglen);
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"DSEL",4)==0) || (strncmp(theMessage->head,"USEL",4)==0)) // Header = DSEL/USEL (Select UDP Send)
|
}
|
||||||
{
|
else if ((head == "MOUS") || (head == "CHAR"))
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"DCOC",4)==0) || (strncmp(theMessage->head,"UCOC",4)==0))
|
}
|
||||||
{
|
else if (head == "MENU")
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"MOUS",4)==0) || (strncmp(theMessage->head,"CHAR",4)==0))
|
}
|
||||||
{
|
else if (head == "SOUN")
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if (strncmp(theMessage->head,"MENU",4)==0)
|
}
|
||||||
{
|
else if ((head == "FAIL") || (head == "RECO"))
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if (strncmp(theMessage->head,"SOUN",4)==0)
|
}
|
||||||
{
|
else if (head == "PAPT")
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"FAIL",4)==0) || (strncmp(theMessage->head,"RECO",4)==0))
|
}
|
||||||
{
|
else if ((head == "VEHN") || head == "VEH1" || (head == "VEHA"))
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if (strncmp(theMessage->head,"PAPT",4)==0)
|
}
|
||||||
{
|
else if ((head == "OBJN") || (head == "OBJL"))
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"VEHN",4)==0) || (strncmp(theMessage->head,"VEH1",4)==0) || (strncmp(theMessage->head,"VEHA",4)==0))
|
}
|
||||||
{
|
else if ((head == "GSET") || (head == "ISET"))
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"OBJN",4)==0) || (strncmp(theMessage->head,"OBJL",4)==0))
|
}
|
||||||
{
|
else if (head == "BOAT")
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{
|
||||||
}
|
sendBUF((char*)msg.GetBuffer(), msg.GetSize()); // Send to UDP
|
||||||
else if ((strncmp(theMessage->head,"GSET",4)==0) || (strncmp(theMessage->head,"ISET",4)==0))
|
}
|
||||||
{
|
else
|
||||||
sendBUF(theMessage->msg,theMessage->msglen); // Send to UDP
|
{ //unrecognized header
|
||||||
}
|
XPC::Log::FormatLine("[EXEC] ERROR: Command %s not recognized", head);
|
||||||
else if (strncmp(theMessage->head, "BOAT", 4) == 0)
|
}
|
||||||
{
|
current_connection = -1;
|
||||||
sendBUF(theMessage->msg, theMessage->msglen); // Send to UDP
|
|
||||||
}
|
return 0;
|
||||||
else
|
|
||||||
{ //unrecognized header
|
|
||||||
XPC::Log::FormatLine("[EXEC] ERROR: Command %s not recognized", theMessage->head);
|
|
||||||
}
|
|
||||||
current_connection = -1;
|
|
||||||
} // end if (buflen > 0)
|
|
||||||
|
|
||||||
return theMessage->msglen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendBUF( char buf[], int buflen)
|
void sendBUF( char buf[], int buflen)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -101,6 +101,7 @@
|
|||||||
<ClInclude Include="..\..\C\src\xplaneConnect.h" />
|
<ClInclude Include="..\..\C\src\xplaneConnect.h" />
|
||||||
<ClInclude Include="..\Drawing.h" />
|
<ClInclude Include="..\Drawing.h" />
|
||||||
<ClInclude Include="..\Log.h" />
|
<ClInclude Include="..\Log.h" />
|
||||||
|
<ClInclude Include="..\Message.h" />
|
||||||
<ClInclude Include="..\UDPSocket.h" />
|
<ClInclude Include="..\UDPSocket.h" />
|
||||||
<ClInclude Include="..\xpcPluginTools.h" />
|
<ClInclude Include="..\xpcPluginTools.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
<ClCompile Include="..\..\C\src\xplaneConnect.c" />
|
<ClCompile Include="..\..\C\src\xplaneConnect.c" />
|
||||||
<ClCompile Include="..\Drawing.cpp" />
|
<ClCompile Include="..\Drawing.cpp" />
|
||||||
<ClCompile Include="..\Log.cpp" />
|
<ClCompile Include="..\Log.cpp" />
|
||||||
|
<ClCompile Include="..\Message.cpp" />
|
||||||
<ClCompile Include="..\UDPSocket.cpp" />
|
<ClCompile Include="..\UDPSocket.cpp" />
|
||||||
<ClCompile Include="..\XPCPlugin.cpp" />
|
<ClCompile Include="..\XPCPlugin.cpp" />
|
||||||
<ClCompile Include="..\xpcPluginTools.cpp" />
|
<ClCompile Include="..\xpcPluginTools.cpp" />
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
<ClInclude Include="..\UDPSocket.h">
|
<ClInclude Include="..\UDPSocket.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Message.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\C\src\xplaneConnect.c">
|
<ClCompile Include="..\..\C\src\xplaneConnect.c">
|
||||||
@@ -50,6 +53,9 @@
|
|||||||
<ClCompile Include="..\UDPSocket.cpp">
|
<ClCompile Include="..\UDPSocket.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Message.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Library Include="..\SDK\Libraries\Win\XPLM.lib">
|
<Library Include="..\SDK\Libraries\Win\XPLM.lib">
|
||||||
|
|||||||
@@ -36,22 +36,6 @@ XPLMDataRef XPLMDataRefs[134][8];
|
|||||||
XPLMDataRef multiplayer[20][17];
|
XPLMDataRef multiplayer[20][17];
|
||||||
XPLMDataRef AIswitch;
|
XPLMDataRef AIswitch;
|
||||||
|
|
||||||
void readMessage(XPC::UDPSocket* socket, struct XPCMessage * pMessage)
|
|
||||||
{
|
|
||||||
pMessage->msglen = socket->Read((std::uint8_t*)pMessage->msg, 5000, &pMessage->recvaddr);
|
|
||||||
|
|
||||||
if ( pMessage->msglen <= 0 ) // No Message
|
|
||||||
{
|
|
||||||
pMessage->msg[0] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strncpy( pMessage->head, pMessage->msg, 4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildXPLMDataRefs()
|
void buildXPLMDataRefs()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -300,146 +284,6 @@ unsigned short getIP(struct sockaddr recvaddr, char *IP)
|
|||||||
|
|
||||||
// DEBUGGING TOOLS
|
// DEBUGGING TOOLS
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
int printBufferToLog(struct XPCMessage & msg)
|
|
||||||
{
|
|
||||||
// Prints the entire buffer to the log (for debugging)
|
|
||||||
char logmsg[350] = "[DEBUG]";
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0;i<msg.msglen && strlen(logmsg)<(sizeof(logmsg)-4);i++)
|
|
||||||
{
|
|
||||||
sprintf(logmsg,"%s %hhu",logmsg,msg.msg[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
|
|
||||||
sprintf(logmsg,"[%s-DEBUG](%i)",msg.head,msg.msg[4]);
|
|
||||||
|
|
||||||
//Switch for header
|
|
||||||
if (strncmp(msg.head,"CONN",4)==0)
|
|
||||||
{// Header = CONN (Connection)
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"SIMU",4)==0)
|
|
||||||
{// Header = SIMU
|
|
||||||
sprintf(logmsg,"%s %i",logmsg,msg.msg[5]);
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"POSI",4)==0)
|
|
||||||
{// Header = POSI (Position)
|
|
||||||
float position[8] = {0.0};
|
|
||||||
float pos[3],orient[3];
|
|
||||||
short aircraft = 0;
|
|
||||||
float gear = -1.0;
|
|
||||||
|
|
||||||
// UPDATE LOG
|
|
||||||
aircraft = parsePOSI(msg.msg,position,6, &gear);
|
|
||||||
|
|
||||||
//ADD AIRCRAFT HANDLING
|
|
||||||
|
|
||||||
// Position
|
|
||||||
memcpy(pos,position,3*sizeof(float));
|
|
||||||
|
|
||||||
// Orientation
|
|
||||||
memcpy(orient,&position[3],3*sizeof(float));
|
|
||||||
|
|
||||||
sprintf(logmsg,"%s %i (%f %f %f) (%f %f %f) %f",logmsg,aircraft,pos[0],pos[1],pos[2],orient[0],orient[1],orient[2],gear);
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"CTRL",4)==0)
|
|
||||||
{// Header = CTRL (Control)
|
|
||||||
xpcCtrl ctrl = parseCTRL(msg.msg);
|
|
||||||
|
|
||||||
sprintf(logmsg,"%s (%f %f %f) %f %hhi %f",logmsg, ctrl.pitch, ctrl.roll, ctrl.yaw, ctrl.throttle, ctrl.gear, ctrl.flaps);
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"WYPT",4)==0)
|
|
||||||
{// Header = WYPT (Waypoint Draw)
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"GETD",4)==0)
|
|
||||||
{// Header = GETD (Data Request)
|
|
||||||
char DREF[100];
|
|
||||||
int counter = 6;
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
|
|
||||||
for (i=0;i<msg.msg[5];i++)
|
|
||||||
{
|
|
||||||
memcpy(DREF,&msg.msg[counter+1],msg.msg[counter]);
|
|
||||||
sprintf(logmsg,"\t#%i/%i (size:%i) %s",i+1,msg.msg[5],msg.msg[counter],DREF);
|
|
||||||
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
memset(DREF,0,sizeof(DREF));
|
|
||||||
|
|
||||||
counter += msg.msg[counter]+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"DREF",4)==0)
|
|
||||||
{// Header = DREF (By Data Ref) (this is slower than DATA)
|
|
||||||
char DREF[100]={0};
|
|
||||||
float tmp;
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
|
|
||||||
memcpy(DREF,&msg.msg[6],msg.msg[5]);
|
|
||||||
sprintf(logmsg,"-\tDREF (size %i)= %s",msg.msg[5],DREF);
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
sprintf(logmsg,"-\tValues(Size %i)=",msg.msg[6+msg.msg[5]]);
|
|
||||||
for (i=0;i<msg.msg[6+msg.msg[5]];i++)
|
|
||||||
{
|
|
||||||
memcpy(&tmp,&msg.msg[7+msg.msg[5]+sizeof(float)*i],sizeof(float));
|
|
||||||
sprintf(logmsg,"%s %f",logmsg,tmp);
|
|
||||||
}
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"VIEW",4)==0)
|
|
||||||
{// Header = VIEW (Change View)
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
}
|
|
||||||
else if (strncmp(msg.head,"DATA",4)==0)
|
|
||||||
{// Header = DATA (UDP Data)
|
|
||||||
int j;
|
|
||||||
short totalColumns = ((msg.msglen-5)/36);
|
|
||||||
float dataRef[30][9];
|
|
||||||
|
|
||||||
sprintf(logmsg,"%s (%i lines)",logmsg,totalColumns);
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
|
|
||||||
totalColumns = parseDATA(msg.msg, msg.msg[4], dataRef);
|
|
||||||
|
|
||||||
for (i=0; i<totalColumns; i++)
|
|
||||||
{
|
|
||||||
sprintf(logmsg,"\t#%i: ",(int) dataRef[i][0]);
|
|
||||||
|
|
||||||
for (j=1; j<9; j++)
|
|
||||||
{
|
|
||||||
sprintf(logmsg,"%s %f",logmsg,dataRef[i][j]);
|
|
||||||
if (dataRef[i][j]!=dataRef[i][j]) sprintf(logmsg,"%s (not a number)",logmsg);
|
|
||||||
}
|
|
||||||
XPC::Log::WriteLine(logmsg);
|
|
||||||
memset(logmsg,0,strlen(logmsg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1; //unrecognized header
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test(const char *buffer)
|
int test(const char *buffer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,17 +19,6 @@
|
|||||||
extern XPLMDataRef multiplayer[20][17];
|
extern XPLMDataRef multiplayer[20][17];
|
||||||
extern XPLMDataRef AIswitch;
|
extern XPLMDataRef AIswitch;
|
||||||
|
|
||||||
struct XPCMessage
|
|
||||||
{
|
|
||||||
short connectionID;
|
|
||||||
char head[5];
|
|
||||||
char msg[5000];
|
|
||||||
int msglen;
|
|
||||||
struct sockaddr recvaddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
void readMessage(XPC::UDPSocket* socket, struct XPCMessage * pMessage);
|
|
||||||
|
|
||||||
void buildXPLMDataRefs(void);
|
void buildXPLMDataRefs(void);
|
||||||
|
|
||||||
int almostequal(float arg1, float arg2, float tol);
|
int almostequal(float arg1, float arg2, float tol);
|
||||||
@@ -39,8 +28,6 @@
|
|||||||
int test(int buffer);
|
int test(int buffer);
|
||||||
|
|
||||||
unsigned short getIP(struct sockaddr recvaddr, char *IP);
|
unsigned short getIP(struct sockaddr recvaddr, char *IP);
|
||||||
|
|
||||||
int printBufferToLog(struct XPCMessage & msg);
|
|
||||||
|
|
||||||
int fmini(int a, int b);
|
int fmini(int a, int b);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user