Initial Version
This commit is contained in:
197
C/User Guide (C).txt
Normal file
197
C/User Guide (C).txt
Normal file
@@ -0,0 +1,197 @@
|
||||
X-Plane Connect-C (XPC-C) Readme
|
||||
XPC-C V0.22 May 21, 2014
|
||||
|
||||
DESCRIPTION
|
||||
XPC-C is a series of C functions that facilitate communication with X-Plane.
|
||||
|
||||
-----------------------------------
|
||||
SETUP
|
||||
Before using XPC Functions you must
|
||||
1. Copy the file XPCPlugin.xpl to the "[X-Plane Directory]/Resources/plugins" directory.
|
||||
2. Put in X-Plane CD 1 or X-Plane USB Key.
|
||||
3. Start X-Plane.
|
||||
4. #include "xplaneConnect.h"
|
||||
|
||||
-----------------------------------
|
||||
BASIC FUNCTIONS
|
||||
1. openUDP opens a UDP Socket for communication. This is used to send data or receive.
|
||||
INPUT:
|
||||
port (unsigned short): Port Number (ex:49067)
|
||||
xpIP (char *): IP Address of the computer running x-plane
|
||||
xpPort (unsigned short): Port number that the X-Plane/ xpcPlugin Receives on (send -1 for default (49009), Typically xpcPlugin is 49009)
|
||||
|
||||
OUTPUT:
|
||||
socket (xpcSocket): The Opened Socket
|
||||
|
||||
USE:
|
||||
unsigned short portNumber = 49067;
|
||||
struct xpcSocket theSocket = openUDP(portNumber);
|
||||
|
||||
2. closeUDP closes an opened UDP Socket for communication. This is to be done after the program has finished using that socket. Use opedUDP to open socket.
|
||||
INPUT:
|
||||
socket (xpcSocket): The Opened Socket
|
||||
|
||||
USE:
|
||||
closeUDP(theSocket);
|
||||
|
||||
3. setCONN sets the return port for requested datarefs.
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
recPort (unsigned Short): Port number for requested dataref values to be sent to
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
setCONN(theSocket,IP,49009,49022); // Sets receive address to 49022;
|
||||
|
||||
4. pauseSim pauses/resumes the x-plane simulation
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
pause (short): 1=Pause, 0=Resume
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
pauseSim(theSocket, IP, 49009, 1);
|
||||
|
||||
5. sendDATA set the value of a state in the "DATA Input & Output" Table
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
dataArray (float[][9]): Array of data to be sent. The first element of each row is the item # (corresponding to the number on the X-Plane "DATA Input & Output" Screen). Send -999 to leave the value unchanged.
|
||||
rows (unsigned short): Number of rows of data being sent
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
float data[] = {{14, 1, -999, -999, -999, -999, -999, -999, -999},{25, 0.8, 0.8, -999, -999, -999, -999, -999, -999}}; // Gear and Throttle
|
||||
sendDATA(theSocket,IP,49009,data,2);
|
||||
|
||||
6. sendPOSI set the position of an aircraft
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
ACNum (short): Number of aircraft to be moved, use 0 for main aircraft (ownPlane).
|
||||
numArgs (short): Number of Arguments to be sent (size of position array)
|
||||
position (float []): Arguments corresponding to aircrafts position
|
||||
position[0] = Latitude
|
||||
position[1] = Longitude
|
||||
position[2] = Altitude (m MSL)
|
||||
position[3] = Roll (deg)
|
||||
position[4] = Pitch (deg)
|
||||
position[5] = True Heading (deg)
|
||||
position[6] = Gear (0=up, 1=down)
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
float posit[] = {37.5242422, -122.06899, 2500, 0, 0, 0, 1};
|
||||
sendPOSI(theSocket, IP, 49009, 7, posit);
|
||||
|
||||
7. sendCTRL send control commands to the aircraft
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
numArgs (short): Number of Arguments to be sent (size of control array)
|
||||
control (float []): Arguments corresponding to aircraft control command
|
||||
control[0] = Latitudinal Stick [-1,1]
|
||||
control[1] = Longitudinal Stick [-1,1]
|
||||
control[2] = Pedal [-1, 1]
|
||||
control[3] = Throttle [-1, 1]
|
||||
control[4] = Gear (0=up, 1=down)
|
||||
control[5] = Flaps [0, 1]
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
float ctrl[] = {0, 0, 0, 0.8, 0, 1};
|
||||
sendCTRL(theSocket, IP, 49009, 6, ctrl);
|
||||
|
||||
8. sendDREF set the value of a specific dataref. Dataref list found at http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html
|
||||
INPUT:
|
||||
socket (xpcSocket): Socket to use to send the command
|
||||
dataRef (char *): Dataref to be set (with or without "sim/" preceeding it)
|
||||
length (short): length of dataref string
|
||||
values (float *): Array of values to be sent
|
||||
length2 (short): Number of values in values array
|
||||
|
||||
OUTPUT:
|
||||
status (short): 0 if successful
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
char theDREF[] = "cockpit/switches/gear_handle_status";
|
||||
float value = 1;
|
||||
sendDREF(theSocket, IP, 49009, theDREF, strlen(theDREF), &value, 1);
|
||||
|
||||
9. requestDREF Request the value of specific dref(s). Dataref list found at http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html
|
||||
INPUT:
|
||||
outSocket (xpcSocket): Socket to use to send the command
|
||||
inSocket (xpcSocket): Socket to use to send the command
|
||||
DREFArray (char[][100]): Array of DataRefs to be requested
|
||||
DREFSizes (int[]): Array of string lengths for each DataRef in DREFArray
|
||||
listLength (short): Number of DataRefs in DREFArray
|
||||
result (*float[]): Array of pointers to the values returned
|
||||
arrayLen (short[]): Array where each element corresponds to the number of elements in the float array.
|
||||
|
||||
OUTPUT:
|
||||
length (short): Number of Values Returned
|
||||
|
||||
USE:
|
||||
char IP[16] = "127.0.0.1";
|
||||
struct xpcSocket theSocket = openUDP(49067);
|
||||
char DREFArray[][100] = {"sim/cockpit/switches/gear_handle_status"};
|
||||
requestDREF(theSocket, IP, 49009, DREFArray, strlen(DREFArray[0]),1);
|
||||
|
||||
-----------------------------------
|
||||
ADVANCED FUNCTIONS (These are mostly used by the xpcPlugin to read requests)
|
||||
1. sendUDP
|
||||
2. readUDP
|
||||
3. readDATA
|
||||
4. parseDATA
|
||||
5. readPOSI
|
||||
6. parsePOSI
|
||||
7. readCTRL
|
||||
8. parseCTRL
|
||||
9. readRequest
|
||||
10. parseRequest
|
||||
11. parseDREF
|
||||
12. readDREF
|
||||
|
||||
-----------------------------------
|
||||
PLANNED FUNCTIONS
|
||||
1. sendVIEW
|
||||
2. parseVIEW
|
||||
3. readVIEW
|
||||
4. sendWYPT
|
||||
5. parseWYPT
|
||||
6. readWYPT
|
||||
7. selectDATA
|
||||
8. sendTEXT
|
||||
9. readTEXT
|
||||
10. parseTEXT
|
||||
|
||||
-----------------------------------
|
||||
CONTACT
|
||||
Email Christopher Teubert (christopher.a.teubert@nasa.gov) with any questions.
|
||||
|
||||
-----------------------------------
|
||||
VERSION HISTORY
|
||||
2014.05.23 (V0.22): (CT) Combined request/readDREF
|
||||
2014.05.21 (V0.21): (CT) Initial Version
|
||||
|
||||
CONTRIBUTORS
|
||||
CT: Christopher Teubert (christopher.a.teubert@nasa.gov)
|
||||
644
C/src/xplaneConnect.c
Normal file
644
C/src/xplaneConnect.c
Normal file
@@ -0,0 +1,644 @@
|
||||
//
|
||||
// xPlaneConnect.c Version 0.25 Beta
|
||||
//
|
||||
// DESCRIPTION
|
||||
// XPLANECONNECT (XPC) Facilitates Communication to and from the XPCPlugin
|
||||
//
|
||||
// REQUIREMENTS
|
||||
// 1. X-Plane Version 9.0 or newer (untested on previous versions)
|
||||
// 2. XPCPlugin.xpl-must be placed in [X-Plane Directory]/Resources/plugins
|
||||
// 3. OS X 10.8 or newer (untested on previous versions)
|
||||
//
|
||||
// INSTRUCTIONS
|
||||
// 1. Include the header "xplaneConnect.h"
|
||||
// EXAMPLE: #include "xplaneConnect.h"
|
||||
// 2. Open UDP Socket using openUDP
|
||||
// EXAMPLE: struct xpcSocket theSocket = openUDP(port_number);
|
||||
// NOTE: Do not send/receive on the same socket
|
||||
// 3. Use functions described below
|
||||
// 4. Close UDP Socket using closeUDP
|
||||
//
|
||||
// NOTICES:
|
||||
// Copyright ã 2013-2014 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved.
|
||||
//
|
||||
// DISCLAIMERS
|
||||
// No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER, GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES IT "AS IS."
|
||||
//
|
||||
// Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT.
|
||||
//
|
||||
// X-Plane API
|
||||
// Copyright (c) 2008, Sandy Barbour and Ben Supnik All rights reserved.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
// * Neither the names of the authors nor that of X-Plane or Laminar Research may be used to endorse or promote products derived from this software without specific prior written permission from the authors or Laminar Research, respectively.
|
||||
//
|
||||
// X-Plane API SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// CONTACT
|
||||
// For questions email Christopher Teubert (christopher.a.teubert@nasa.gov)
|
||||
//
|
||||
// VERSION HISTORY
|
||||
// 06.24.14 (V0.23): (CT) General Fixes for Windows compatability
|
||||
// 05.23.14 (V0.22): (CT) Combined request/readDREF
|
||||
// -fixed readPOSI (gear issue)
|
||||
// 05.21.14 (V0.2175): (CT) Added Throttle to CTRL
|
||||
// 05.12.14 (V0.215): (CT) Read/Parse/Send Control
|
||||
// 05.07.14 (V0.21): (CT) Read/Parse/Send Position
|
||||
// 04.29.14 (V0.205): (CT) Added check that data was received in read functions
|
||||
// 03.15.14 (V0.2): (CT) General performance updates, added preconditions
|
||||
// 02.04.14 (V0.11): (CT) Fixed problem that caused for loops not to work with some compilers. General Stability Improvements, added readRequest, readDREF
|
||||
// 01.27.14 (V0.1): (CT) First Beta: sendDATA, sendDREF, requestDREF, pauseSim, readDATA
|
||||
// 11.10.13 (V0.0): (CT) First Version
|
||||
//
|
||||
// CONTRIBUTORS
|
||||
// CT: Christopher Teubert (christopher.a.teubert@nasa.gov)
|
||||
//
|
||||
// TO DO
|
||||
// 1. Update SelectData
|
||||
// 2. RequestDREF: look into removing DREFSizes
|
||||
//
|
||||
// BEGIN CODE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
#ifdef _WIN32 /* WIN32 SYSTEM */
|
||||
#include <WS2tcpip.h>
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define snprintf sprintf_s
|
||||
#define socklen_t int
|
||||
|
||||
void usleep(__int64 usec)
|
||||
{ // From http://www.c-plusplus.de/forum/109539-full
|
||||
HANDLE timer;
|
||||
LARGE_INTEGER ft;
|
||||
|
||||
ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
|
||||
|
||||
timer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
|
||||
WaitForSingleObject(timer, INFINITE);
|
||||
CloseHandle(timer);
|
||||
}
|
||||
#endif
|
||||
|
||||
short errorReport(char *functionName, char *errorMessage);
|
||||
short sendRequest(struct xpcSocket recfd, char DREFArray[][100], short DREFSizes[], short listLength);
|
||||
|
||||
short errorReport(char *functionName, char *errorMessage)
|
||||
{
|
||||
printf("ERROR: %s-%s\n", functionName, errorMessage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct xpcSocket openUDP(unsigned short port_number, const char *xpIP, unsigned short xpPort)
|
||||
{
|
||||
struct xpcSocket theSocket;
|
||||
struct sockaddr_in server;
|
||||
|
||||
#if (__APPLE__ || __linux)
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
// Setup Port
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons(port_number);
|
||||
|
||||
// Set X-Plane Port and IP
|
||||
if (strcasecmp(xpIP,"localhost") == 0) // IP
|
||||
{
|
||||
strncpy(theSocket.xpIP,"127.0.0.1",9); // Default
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(theSocket.xpIP,xpIP,(size_t) fminl(strlen(xpIP),16));
|
||||
}
|
||||
|
||||
if (xpPort <= 0) // Default Port
|
||||
{
|
||||
theSocket.xpPort = 49009; // Default
|
||||
}
|
||||
else
|
||||
{
|
||||
theSocket.xpPort = xpPort;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsa;
|
||||
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
|
||||
{
|
||||
perror("ERROR: openUDP- ");
|
||||
return theSocket;
|
||||
//ERROR IN Socket Message
|
||||
}
|
||||
|
||||
if ((theSocket.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
|
||||
{
|
||||
perror("ERROR: openUDP- ");
|
||||
return theSocket;
|
||||
//ERROR IN Socket Message
|
||||
}
|
||||
|
||||
if (bind(theSocket.sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
|
||||
{
|
||||
perror("ERROR: openUDP- ");
|
||||
return theSocket;
|
||||
//ERROR IN Socket Message
|
||||
}
|
||||
#elif (__APPLE__ || __linux)
|
||||
// Create a SOCKET
|
||||
theSocket.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if ((theSocket.sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
{
|
||||
perror((char*) "ERROR: openUDP- ");
|
||||
return theSocket;
|
||||
}
|
||||
|
||||
//Bind
|
||||
if ( bind(theSocket.sock, (struct sockaddr *) &server, sizeof(server)) == -1)
|
||||
{
|
||||
perror( (char*) "ERROR: openUDP- ");
|
||||
return theSocket;
|
||||
}
|
||||
#endif
|
||||
|
||||
//Set Timout
|
||||
int msTimeOut = 500;
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD msTimeOutWin = 1;
|
||||
setsockopt(theSocket.sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&msTimeOutWin, sizeof(msTimeOutWin));
|
||||
#else
|
||||
tv.tv_sec = 0; /* Sec Timeout */
|
||||
tv.tv_usec = msTimeOut; // Microsec Timeout
|
||||
setsockopt(theSocket.sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval));
|
||||
#endif
|
||||
|
||||
return theSocket;
|
||||
}
|
||||
|
||||
void closeUDP(struct xpcSocket socketNumber)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket(socketNumber.sock);
|
||||
#elif (__APPLE__ || __linux)
|
||||
close(socketNumber.sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
short sendUDP(struct xpcSocket recfd, char my_message[], short messageLength)
|
||||
{
|
||||
struct sockaddr_in servaddr;
|
||||
|
||||
my_message[4] = (char) messageLength;
|
||||
|
||||
// Preconditions
|
||||
if (messageLength <= 0)// Positive Message Length
|
||||
{
|
||||
return errorReport("sendUDP", "message length must be positive >0");
|
||||
}
|
||||
|
||||
// Code
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(recfd.xpPort);
|
||||
servaddr.sin_addr.s_addr = inet_addr(recfd.xpIP);
|
||||
|
||||
#ifdef _WIN32
|
||||
const char on = 1;
|
||||
#else
|
||||
int on=1;
|
||||
#endif
|
||||
|
||||
setsockopt(recfd.sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
|
||||
|
||||
if (sendto(recfd.sock, my_message, (int) messageLength, 0, (const struct sockaddr *) &servaddr, sizeof(servaddr))<0)
|
||||
{
|
||||
perror("ERROR: sendUDP-");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendDATA(struct xpcSocket recfd, float dataRef[][9], unsigned short rows)
|
||||
{
|
||||
int i;
|
||||
unsigned short length = rows*9*sizeof(float) + 5;
|
||||
char message[5000];
|
||||
unsigned short step = 9*sizeof(float);
|
||||
|
||||
strncpy(message,"DATA",4);
|
||||
|
||||
for (i=0;i<rows;i++)
|
||||
{
|
||||
message[5+i*step] = (char) dataRef[i][0];
|
||||
message[6+i*step] = (char) 0;
|
||||
message[7+i*step] = (char) 0;
|
||||
message[8+i*step] = (char) 0;
|
||||
memcpy(&message[9+i*step], &dataRef[i][1], 8*sizeof(float));
|
||||
}
|
||||
|
||||
sendUDP(recfd, message, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendDREF(struct xpcSocket recfd, const char *dataRef, unsigned short length_of_DREF, float *values, unsigned short number_of_values) {
|
||||
char message[5000];
|
||||
int length = 6+length_of_DREF+number_of_values*sizeof(float);
|
||||
|
||||
//HEADER
|
||||
strncpy(message,"DREF",4);
|
||||
|
||||
//DREF
|
||||
message[5] = (char) length_of_DREF;
|
||||
memcpy(&message[6],dataRef,length_of_DREF);
|
||||
|
||||
//VALUES
|
||||
message[length_of_DREF+6] = (char) number_of_values;
|
||||
memcpy(&message[length_of_DREF+7],&values[0],sizeof(float)*number_of_values);
|
||||
|
||||
sendUDP(recfd, message, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendRequest(struct xpcSocket recfd, char DREFArray[][100], short DREFSizes[], short listLength)
|
||||
{
|
||||
int i;
|
||||
char message[5000]={0};
|
||||
int length = 6;
|
||||
|
||||
//HEADER
|
||||
strncpy(message,"GETD",4);
|
||||
|
||||
message[5] = (char) listLength; //Number of Values
|
||||
|
||||
//The rest
|
||||
for (i=0; i < listLength; i++)
|
||||
{
|
||||
message[length] = (char) DREFSizes[i];
|
||||
memcpy(&message[length+1],DREFArray[i],message[length]);
|
||||
length += message[length] + 1;
|
||||
}
|
||||
|
||||
sendUDP(recfd, message, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short requestDREF(struct xpcSocket sendfd, struct xpcSocket recfd, char DREFArray[][100], short DREFSizes[], short listLength, float *resultArray[], short arraySizes[])
|
||||
{
|
||||
int i;
|
||||
|
||||
sendRequest(sendfd, DREFArray, DREFSizes, listLength);
|
||||
|
||||
for (i=0; i<40; i++)
|
||||
{
|
||||
int size = readDREF(recfd, resultArray, arraySizes);
|
||||
if (size != -1) // Received input
|
||||
{
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
short pauseSim(struct xpcSocket recfd, short pause)
|
||||
{
|
||||
char message[7];
|
||||
|
||||
//Preconditions
|
||||
if (pause != 0 && pause != 1)
|
||||
{
|
||||
return errorReport("pauseSim", "Please set pause to 0 or 1");
|
||||
}
|
||||
|
||||
strncpy(message,"SIMU",4);
|
||||
message[5] = (char) pause;
|
||||
message[6] = 0;
|
||||
|
||||
sendUDP(recfd, message,6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short setCONN(struct xpcSocket recfd, unsigned short recPort)
|
||||
{
|
||||
char message[10] = {0};
|
||||
int length;
|
||||
strncpy(message,"CONN",4);
|
||||
|
||||
memcpy(&message[5],&recPort,sizeof(recPort));
|
||||
|
||||
length = 5 + sizeof(recPort);
|
||||
|
||||
sendUDP(recfd,message, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendPOSI(struct xpcSocket recfd, short ACNum, short numArgs, float valueArray[])
|
||||
{
|
||||
char message[40] = {0};
|
||||
int i;
|
||||
short position = 6;
|
||||
|
||||
// Input Verification
|
||||
if (numArgs < 1)
|
||||
{
|
||||
return errorReport("POSI", "Must have atleast one argument");
|
||||
}
|
||||
|
||||
// Header
|
||||
strncpy(message,"POSI",4);
|
||||
|
||||
// Aircraft
|
||||
message[5] = (char) ACNum;
|
||||
|
||||
// States
|
||||
|
||||
for (i=0; i<7; i++)
|
||||
{
|
||||
float val = -998.5;
|
||||
|
||||
if ( i < numArgs )
|
||||
{
|
||||
val = valueArray[i];
|
||||
}
|
||||
|
||||
memcpy(&message[position],&val,sizeof(float));
|
||||
position += sizeof(float);
|
||||
}
|
||||
|
||||
sendUDP(recfd, message, position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short sendCTRL(struct xpcSocket recfd, short numArgs, float valueArray[])
|
||||
{
|
||||
char message[22] = {0};
|
||||
int i;
|
||||
short position = 5;
|
||||
|
||||
// Input Verification
|
||||
if (numArgs < 1)
|
||||
{
|
||||
return errorReport("CTRL", "Must have atleast one argument");
|
||||
}
|
||||
|
||||
// Header
|
||||
strncpy(message,"CTRL",4);
|
||||
|
||||
// States
|
||||
for (i=0;i<6;i++)
|
||||
{
|
||||
float val = -998.5;
|
||||
|
||||
if (i<numArgs)
|
||||
{
|
||||
val = valueArray[i];
|
||||
}
|
||||
|
||||
// Float Values
|
||||
memcpy(&message[position],&val,sizeof(float));
|
||||
position += sizeof(float);
|
||||
}
|
||||
|
||||
sendUDP(recfd, message, 22);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//READ
|
||||
//----------------------------------------
|
||||
int readUDP(struct xpcSocket recfd, char *dataRef, struct sockaddr *recvaddr)
|
||||
{
|
||||
socklen_t recvaddrlen = sizeof(*recvaddr);
|
||||
int status = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows readUDP needs the select command- minimum timeout is 1ms.
|
||||
// Without this playback becomes choppy
|
||||
|
||||
// Definitions
|
||||
FD_SET stReadFDS;
|
||||
FD_SET stExceptFDS;
|
||||
struct timeval tv;
|
||||
struct sockaddr_in testaddr;
|
||||
int error = 0;
|
||||
|
||||
// Setup for Select
|
||||
FD_ZERO(&stReadFDS);
|
||||
FD_SET(recfd.sock, &stReadFDS);
|
||||
FD_ZERO(&stExceptFDS);
|
||||
FD_SET(recfd.sock, &stExceptFDS);
|
||||
tv.tv_sec = 0; /* Sec Timeout */
|
||||
tv.tv_usec = 250; // Microsec Timeout
|
||||
|
||||
// Select Command
|
||||
int tmp = select(-1, &stReadFDS, (FD_SET *)0, &stExceptFDS, &tv);
|
||||
if (tmp <= 0) // No Data or error
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If no error: Read Data
|
||||
recvaddrlen = sizeof(testaddr);
|
||||
status = (int) recvfrom(recfd.sock,dataRef,5000,0,(SOCKADDR *) &testaddr,&recvaddrlen);
|
||||
if (status == SOCKET_ERROR)
|
||||
{
|
||||
error = WSAGetLastError();
|
||||
}
|
||||
#else
|
||||
// For apple or linux-just read - will timeout in 0.5 ms
|
||||
status = (int) recvfrom(recfd.sock,dataRef,5000,0,recvaddr,&recvaddrlen);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
short readDATA(struct xpcSocket recfd, float dataRef[][9])
|
||||
{
|
||||
char buf[5000];
|
||||
int buflen = readUDP(recfd,buf, NULL);
|
||||
|
||||
if (buf[0]!= '\0')
|
||||
{
|
||||
return parseDATA(buf, buflen, dataRef);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
short readRequest(struct xpcSocket recfd, float *dataRef[], short arraySizes[], struct sockaddr *recvaddr)
|
||||
{
|
||||
char buf[5000];
|
||||
readUDP(recfd,buf, recvaddr);
|
||||
if (buf[0]!= '\0')
|
||||
{
|
||||
return parseRequest(buf, dataRef, arraySizes);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
short readDREF(struct xpcSocket recfd, float *resultArray[], short arraySizes[])
|
||||
{
|
||||
char buf[5000] = {0};
|
||||
readUDP(recfd,buf, NULL);
|
||||
|
||||
if (buf[0]!= '\0')
|
||||
{
|
||||
return parseRequest(buf, resultArray, arraySizes);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
short readPOSI(struct xpcSocket recfd, float resultArray[], int arraySize, float *gear)
|
||||
{
|
||||
char buf[5000] = {0};
|
||||
readUDP(recfd,buf, NULL);
|
||||
|
||||
if (buf[0]!= '\0') // Buffer is not empty
|
||||
{
|
||||
return parsePOSI(buf, resultArray, arraySize, gear);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
float readCTRL(struct xpcSocket recfd, float resultArray[4], short *gear)
|
||||
{
|
||||
char buf[5000] = {0};
|
||||
readUDP(recfd,buf, NULL);
|
||||
|
||||
if (buf[0] != '\0') // Buffer is not empty
|
||||
{
|
||||
return parseCTRL(buf, resultArray, gear);
|
||||
}
|
||||
|
||||
return NAN;
|
||||
}
|
||||
|
||||
//PARSE
|
||||
//---------------------
|
||||
short parseDATA(const char my_message[], short messageLength, float dataRef[][9])
|
||||
{
|
||||
int i, j;
|
||||
unsigned short totalColumns = ((messageLength-5)/36);
|
||||
float *tmp;
|
||||
float data[20][9];
|
||||
tmp = malloc(sizeof(float));
|
||||
|
||||
// Input Validation
|
||||
|
||||
for (i=0;i<totalColumns;i++)
|
||||
{
|
||||
data[i][0] = my_message[5+36*i];
|
||||
for (j=1;j<9;j++)
|
||||
{
|
||||
memcpy(tmp,&my_message[5]+4*j+36*i,4);
|
||||
data[i][j] = *tmp;
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
memcpy(dataRef,data,sizeof(data));
|
||||
return totalColumns;
|
||||
}
|
||||
|
||||
short parseDREF(const char my_message[], char *dataRef, unsigned short *length_of_DREF, float *values, unsigned short *number_of_values)
|
||||
{
|
||||
*length_of_DREF = (unsigned short) my_message[5];
|
||||
memcpy(dataRef,&(my_message[6]),*length_of_DREF);
|
||||
*number_of_values = (unsigned short) my_message[6+*length_of_DREF];
|
||||
memcpy(values,&my_message[*length_of_DREF+7],*number_of_values*sizeof(float));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parseGETD(const char my_message[], char *DREFArray[], int DREFSizes[])
|
||||
{
|
||||
int i;
|
||||
int listLength = my_message[5];
|
||||
int counter = 6;
|
||||
|
||||
for (i=0; i<listLength;i++)
|
||||
{
|
||||
DREFSizes[i] = my_message[counter];
|
||||
memcpy(DREFArray[i],&my_message[counter+1],DREFSizes[i]);
|
||||
counter += DREFSizes[i]+1;
|
||||
}
|
||||
|
||||
return listLength;
|
||||
}
|
||||
|
||||
short parseRequest(const char my_message[], float *resultArray[], short arraySizes[])
|
||||
{
|
||||
int i, j;
|
||||
short count = my_message[5];
|
||||
short place = 6;
|
||||
float *tmp;
|
||||
float data[10];
|
||||
tmp = malloc(sizeof(float));
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
arraySizes[i] = my_message[place];
|
||||
if (arraySizes[i] > 1) realloc(resultArray[i],arraySizes[i]);
|
||||
|
||||
for (j=0; j< arraySizes[i]; j++)
|
||||
{
|
||||
memcpy(tmp,&my_message[place+1],sizeof(float));
|
||||
data[j] = *tmp;
|
||||
}
|
||||
|
||||
resultArray[i] = malloc(arraySizes[i]*sizeof(float));
|
||||
|
||||
memcpy(resultArray[i],&data,arraySizes[i]*sizeof(float));
|
||||
place += 1 + arraySizes[i]*sizeof(float);
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
return count;
|
||||
}
|
||||
|
||||
short parsePOSI(const char my_message[], float resultArray[], int arraySize, float *gear)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Input Validation
|
||||
if (arraySize < 1) return -1;
|
||||
|
||||
memcpy(gear,&my_message[30],4);
|
||||
|
||||
for (i=0; (i<arraySize && i < 6); i++)
|
||||
{
|
||||
memcpy(&resultArray[i],&my_message[i*4+6],4);
|
||||
}
|
||||
|
||||
return my_message[5]; // Aircraft
|
||||
}
|
||||
|
||||
float parseCTRL(const char my_message[], float resultArray[], short *gear)
|
||||
{
|
||||
int i;
|
||||
float flaps = 0;
|
||||
|
||||
// Controls
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
memcpy(&resultArray[i],&my_message[5+4*i],4);
|
||||
}
|
||||
|
||||
// Gear, Flaps
|
||||
*gear = (short) my_message[21];
|
||||
|
||||
memcpy(&flaps,&my_message[22],4);
|
||||
|
||||
return flaps;
|
||||
}
|
||||
78
C/src/xplaneConnect.h
Normal file
78
C/src/xplaneConnect.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// xplaneConnect.h
|
||||
//
|
||||
// Created by Chris Teubert on 12/2/13.
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef xplaneConnect_h
|
||||
#define xplaneConnect_h
|
||||
|
||||
#ifdef _WIN32 /* WIN32 SYSTEM */
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib,"ws2_32.lib") //Winsock Library
|
||||
#elif (__APPLE__ || __linux)
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
struct xpcSocket {
|
||||
short open;
|
||||
unsigned short port;
|
||||
|
||||
// X-Plane IP and Port
|
||||
char xpIP[16];
|
||||
unsigned short xpPort;
|
||||
|
||||
#ifdef _WIN32 /* WIN32 SYSTEM */
|
||||
SOCKET sock;
|
||||
#elif (__APPLE__ || __linux) //OS X/Linux
|
||||
int sock;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Basic Functions
|
||||
struct xpcSocket openUDP(unsigned short port, const char *xpIP, unsigned short xpPort);
|
||||
void closeUDP(struct xpcSocket);
|
||||
short sendUDP(struct xpcSocket recfd, char my_message[], short messageLength);
|
||||
int readUDP(struct xpcSocket recfd, char *dataRef, struct sockaddr *recvaddr);
|
||||
|
||||
// Configuration
|
||||
short setCONN(struct xpcSocket recfd, unsigned short recPort);
|
||||
short pauseSim(struct xpcSocket recfd, short);
|
||||
|
||||
// UDP DATA
|
||||
short parseDATA(const char my_message[], short messageLength, float dataRef[][9]);
|
||||
short readDATA(struct xpcSocket recfd, float dataRef[][9]);
|
||||
short sendDATA(struct xpcSocket recfd, float dataRef[][9], unsigned short rows);
|
||||
|
||||
// Position
|
||||
short parsePOSI(const char my_message[], float resultArray[], int arraySize, float *gear);
|
||||
short readPOSI(struct xpcSocket recfd, float resultArray[], int arraySize, float *gear);
|
||||
short sendPOSI(struct xpcSocket recfd, short ACNum, short numArgs, float valueArray[]);
|
||||
|
||||
// Controls
|
||||
float parseCTRL(const char my_message[], float resultArray[4], short *gear);
|
||||
float readCTRL(struct xpcSocket recfd, float resultArray[4], short *gear);
|
||||
short sendCTRL(struct xpcSocket recfd, short numArgs, float valueArray[]);
|
||||
|
||||
// DREF Manipulation
|
||||
short readDREF(struct xpcSocket recfd, float *resultArray[], short arraySizes[]);
|
||||
short parseDREF(const char my_message[], char *dataRef, unsigned short *length_of_DREF, float *values, unsigned short *number_of_values);
|
||||
short sendDREF(struct xpcSocket recfd, const char *dataRef, unsigned short length_of_DREF, float *values, unsigned short number_of_values);
|
||||
short requestDREF(struct xpcSocket sendfd, struct xpcSocket recfd, char DREFArray[][100], short DREFSizes[], short listLength, float *resultArray[], short arraySizes[]);
|
||||
int parseGETD(const char my_message[], char *DREFArray[], int DREFSizes[]);
|
||||
short parseRequest(const char my_message[], float *resultArray[], short arraySizes[]);
|
||||
short readRequest(struct xpcSocket recfd, float *dataRef[], short arraySizes[], struct sockaddr *recvaddr);
|
||||
|
||||
#endif //ifdef _h
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
259
C/xpcExample/xpcExample.xcodeproj/project.pbxproj
Normal file
259
C/xpcExample/xpcExample.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,259 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
BEDC620118EDF0F5005DB364 /* xplaneConnect.c in Sources */ = {isa = PBXBuildFile; fileRef = BEDC61FF18EDF0F5005DB364 /* xplaneConnect.c */; };
|
||||
BEDC620818EDF254005DB364 /* xplaneConnect.c in CopyFiles */ = {isa = PBXBuildFile; fileRef = BEDC61FF18EDF0F5005DB364 /* xplaneConnect.c */; };
|
||||
BEDC620918EDF257005DB364 /* xplaneConnect.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = BEDC620018EDF0F5005DB364 /* xplaneConnect.h */; };
|
||||
BEF9890F18E4E7F7005554D1 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BEF9890E18E4E7F7005554D1 /* main.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
BE60308318E5F7A5004B5E1D /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 12;
|
||||
dstPath = /Users/cteubert/Documents/flightdeckz/connections/src/xplaneconnect;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
BEDC620818EDF254005DB364 /* xplaneConnect.c in CopyFiles */,
|
||||
BEDC620918EDF257005DB364 /* xplaneConnect.h in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
BEDC61FF18EDF0F5005DB364 /* xplaneConnect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xplaneConnect.c; path = ../src/xplaneConnect.c; sourceTree = "<group>"; };
|
||||
BEDC620018EDF0F5005DB364 /* xplaneConnect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xplaneConnect.h; path = ../src/xplaneConnect.h; sourceTree = "<group>"; };
|
||||
BEF9890B18E4E7F7005554D1 /* xpcExample */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xpcExample; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BEF9890E18E4E7F7005554D1 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
BEF9890818E4E7F7005554D1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
BE60308618E5F980004B5E1D /* xplaneConnect */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BEDC61FF18EDF0F5005DB364 /* xplaneConnect.c */,
|
||||
BEDC620018EDF0F5005DB364 /* xplaneConnect.h */,
|
||||
);
|
||||
name = xplaneConnect;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BEF9890218E4E7F7005554D1 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BEF9890D18E4E7F7005554D1 /* xpcExample */,
|
||||
BE60308618E5F980004B5E1D /* xplaneConnect */,
|
||||
BEF9890C18E4E7F7005554D1 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BEF9890C18E4E7F7005554D1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BEF9890B18E4E7F7005554D1 /* xpcExample */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BEF9890D18E4E7F7005554D1 /* xpcExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BEF9890E18E4E7F7005554D1 /* main.cpp */,
|
||||
);
|
||||
path = xpcExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
BEF9890A18E4E7F7005554D1 /* xpcExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = BEF9891418E4E7F7005554D1 /* Build configuration list for PBXNativeTarget "xpcExample" */;
|
||||
buildPhases = (
|
||||
BEF9890718E4E7F7005554D1 /* Sources */,
|
||||
BEF9890818E4E7F7005554D1 /* Frameworks */,
|
||||
BE60308318E5F7A5004B5E1D /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = xpcExample;
|
||||
productName = xpcExample;
|
||||
productReference = BEF9890B18E4E7F7005554D1 /* xpcExample */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
BEF9890318E4E7F7005554D1 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Chris Teubert";
|
||||
};
|
||||
buildConfigurationList = BEF9890618E4E7F7005554D1 /* Build configuration list for PBXProject "xpcExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = BEF9890218E4E7F7005554D1;
|
||||
productRefGroup = BEF9890C18E4E7F7005554D1 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
BEF9890A18E4E7F7005554D1 /* xpcExample */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
BEF9890718E4E7F7005554D1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
BEDC620118EDF0F5005DB364 /* xplaneConnect.c in Sources */,
|
||||
BEF9890F18E4E7F7005554D1 /* main.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
BEF9891218E4E7F7005554D1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
BEF9891318E4E7F7005554D1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
BEF9891518E4E7F7005554D1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/Users/cteubert/Documents/xplaneconnect/xpcPlugin,
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
BEF9891618E4E7F7005554D1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
/Users/cteubert/Documents/xplaneconnect/xpcPlugin,
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
BEF9890618E4E7F7005554D1 /* Build configuration list for PBXProject "xpcExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
BEF9891218E4E7F7005554D1 /* Debug */,
|
||||
BEF9891318E4E7F7005554D1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
BEF9891418E4E7F7005554D1 /* Build configuration list for PBXNativeTarget "xpcExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
BEF9891518E4E7F7005554D1 /* Debug */,
|
||||
BEF9891618E4E7F7005554D1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = BEF9890318E4E7F7005554D1 /* Project object */;
|
||||
}
|
||||
7
C/xpcExample/xpcExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
C/xpcExample/xpcExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:xpcExample.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>2D8FADF5-8504-4A76-A99F-91CA115CE4E3</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>xpcExample</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>D7B4D224-FE26-406E-A48F-C604A5BE6975</key>
|
||||
<string>https://babelfish.arc.nasa.gov/svn/pcoe/cteubert/xplaneconnect</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>C/xpcExample/xpcExample.xcodeproj/project.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>D7B4D224-FE26-406E-A48F-C604A5BE6975</key>
|
||||
<string>../../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectRepositoryRootDictionary</key>
|
||||
<dict>
|
||||
<key>D7B4D224-FE26-406E-A48F-C604A5BE6975</key>
|
||||
<string>https://babelfish.arc.nasa.gov/svn/pcoe</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>https://babelfish.arc.nasa.gov/svn/pcoe/cteubert/xplaneconnect/C/xpcExample/xpcExample.xcodeproj</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>D7B4D224-FE26-406E-A48F-C604A5BE6975</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.subversion</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>D7B4D224-FE26-406E-A48F-C604A5BE6975</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>xplaneconnect</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../src/xplaneConnect.c"
|
||||
timestampString = "433458275.8587"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "342"
|
||||
endingLineNumber = "342"
|
||||
landmarkName = "setCONN()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>xpcExample.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>BEF9890A18E4E7F7005554D1</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0500"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BEF9890A18E4E7F7005554D1"
|
||||
BuildableName = "xpcExample"
|
||||
BlueprintName = "xpcExample"
|
||||
ReferencedContainer = "container:xpcExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BEF9890A18E4E7F7005554D1"
|
||||
BuildableName = "xpcExample"
|
||||
BlueprintName = "xpcExample"
|
||||
ReferencedContainer = "container:xpcExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BEF9890A18E4E7F7005554D1"
|
||||
BuildableName = "xpcExample"
|
||||
BlueprintName = "xpcExample"
|
||||
ReferencedContainer = "container:xpcExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "BEF9890A18E4E7F7005554D1"
|
||||
BuildableName = "xpcExample"
|
||||
BlueprintName = "xpcExample"
|
||||
ReferencedContainer = "container:xpcExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
131
C/xpcExample/xpcExample/main.cpp
Normal file
131
C/xpcExample/xpcExample/main.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// main.cpp
|
||||
// xpcExample
|
||||
//
|
||||
// Created by Chris Teubert on 3/27/14.
|
||||
// Copyright (c) 2014 Chris Teubert. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "xplaneConnect.h"
|
||||
|
||||
int main() {
|
||||
int i,j;
|
||||
struct xpcSocket sendfd,readfd;
|
||||
float data[4][9] = {0};
|
||||
char DREF[100] = {0};
|
||||
char DREFArray[100][100];
|
||||
char DREFArray2[100][100];
|
||||
short DREFSizes[100];
|
||||
float *recDATA[100];
|
||||
float POSI[9] = {0.0};
|
||||
float CTRL[5] = {0.0};
|
||||
float gear;
|
||||
char IP[16] = "143.232.73.41";//"127.0.0.1";//;// //IP Address of computer running X-Plane
|
||||
short PORT = 49009; //xpcPlugin Receiving port (usually 49009)
|
||||
|
||||
printf("xplaneconnect Example Script\n- Setting up Simulation\n");
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
recDATA[i] = (float *) malloc(40*sizeof(float));
|
||||
memset(DREFArray[i],0,100);
|
||||
memset(DREFArray2[i],0,100);
|
||||
}
|
||||
|
||||
// Open Sockets
|
||||
readfd = openUDP(49055, IP, PORT); //Open socket for receiving
|
||||
sendfd = openUDP(49077, IP, PORT); //Open socket for sending
|
||||
|
||||
// Set up Connection
|
||||
setCONN(sendfd, 49055); // Setup so data will be received on port 49055
|
||||
|
||||
// Set Location/Orientation (sendPOSI)
|
||||
// Set Up Position Array
|
||||
POSI[0] = 37.524; // Lat
|
||||
POSI[1] = -122.06899; // Lon
|
||||
POSI[2] = 2500; // Alt
|
||||
POSI[3] = 0; // Pitch
|
||||
POSI[4] = 0; // Roll
|
||||
POSI[5] = 0; // Heading
|
||||
POSI[6] = 1; // Gear
|
||||
|
||||
sendPOSI(sendfd, 0, 7, POSI);
|
||||
POSI[0] = 37.52465;
|
||||
POSI[4] = 20;
|
||||
sendPOSI(sendfd, 1, 7, POSI);
|
||||
|
||||
// Set Rates (sendDATA)
|
||||
|
||||
for (i=0;i<4;i++) { // Set array to -999
|
||||
for (j=0;j<9;j++) data[i][j] = -999;
|
||||
}
|
||||
// Set up Data Array (first item in row is item number (example: 20=position)
|
||||
data[0][0] = 18; // Alpha
|
||||
data[0][1] = 0;
|
||||
data[0][3] = 0;
|
||||
|
||||
data[1][0] = 3;//21; //Velocity
|
||||
data[1][1] = 130;
|
||||
data[1][2] = 130;
|
||||
data[1][3] = 130;
|
||||
data[1][4] = 130;
|
||||
|
||||
data[2][0] = 16; //PQR
|
||||
data[2][1] = 0;
|
||||
data[2][2] = 0;
|
||||
data[2][3] = 0;
|
||||
|
||||
sendDATA(sendfd, data, 3); // Throttle/Velocity/Alpha/PQR
|
||||
|
||||
// Set CTRL
|
||||
CTRL[3] = 0.8; // Throttle
|
||||
|
||||
sendCTRL(sendfd, 4, CTRL);
|
||||
|
||||
// pauseSim
|
||||
pauseSim(sendfd, 1); // Sending 1 to pause
|
||||
|
||||
// Pause for 5 seconds
|
||||
sleep(5);
|
||||
|
||||
// Unpause
|
||||
pauseSim(sendfd, 0); // Sending 0 to unpause
|
||||
printf("- Resuming Simulation\n");
|
||||
|
||||
// Simulate for 10 seconds
|
||||
sleep(10);
|
||||
|
||||
// SendDREF (Landing Gear)
|
||||
printf("- Stowing Landing Gear\n");
|
||||
|
||||
strcpy(DREF,"cockpit/switches/gear_handle_status"); // Gear handle data reference
|
||||
DREFSizes[0] = sizeof(DREF);
|
||||
gear = 1; // Stow gear
|
||||
|
||||
sendDREF(sendfd, DREF, DREFSizes[0], &gear, 1); // Set gear to stow
|
||||
|
||||
// Simulate for 10 seconds
|
||||
sleep(10);
|
||||
|
||||
// Check Landing gear, Pause
|
||||
printf("- Confirming Gear Status\n");
|
||||
strcpy(DREFArray2[0],"sim/cockpit/switches/gear_handle_status");
|
||||
strcpy(DREFArray2[1],"sim/operation/override/override_planepath");
|
||||
for (i=0;i<2;i++) {
|
||||
DREFSizes[i] = (int) strlen(DREFArray2[i]);
|
||||
}
|
||||
requestDREF(sendfd, readfd, DREFArray2, DREFSizes, 2, recDATA, DREFSizes); // Request 2 values
|
||||
|
||||
if (*(recDATA[0])==0) {
|
||||
printf("\tGear Stowed\n");
|
||||
} else {
|
||||
printf("\tERROR: Gear Stowage unsuccessful\n");
|
||||
}
|
||||
|
||||
printf("---End Program---\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
79
C/xpcExample/xpcExample/xpcExample.1
Normal file
79
C/xpcExample/xpcExample/xpcExample.1
Normal file
@@ -0,0 +1,79 @@
|
||||
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
|
||||
.\"See Also:
|
||||
.\"man mdoc.samples for a complete listing of options
|
||||
.\"man mdoc for the short list of editing options
|
||||
.\"/usr/share/misc/mdoc.template
|
||||
.Dd 3/27/14 \" DATE
|
||||
.Dt xpcExample 1 \" Program name and manual section number
|
||||
.Os Darwin
|
||||
.Sh NAME \" Section Header - required - don't modify
|
||||
.Nm xpcExample,
|
||||
.\" The following lines are read in generating the apropos(man -k) database. Use only key
|
||||
.\" words here as the database is built based on the words here and in the .ND line.
|
||||
.Nm Other_name_for_same_program(),
|
||||
.Nm Yet another name for the same program.
|
||||
.\" Use .Nm macro to designate other names for the documented program.
|
||||
.Nd This line parsed for whatis database.
|
||||
.Sh SYNOPSIS \" Section Header - required - don't modify
|
||||
.Nm
|
||||
.Op Fl abcd \" [-abcd]
|
||||
.Op Fl a Ar path \" [-a path]
|
||||
.Op Ar file \" [file]
|
||||
.Op Ar \" [file ...]
|
||||
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
|
||||
arg2 ... \" Arguments
|
||||
.Sh DESCRIPTION \" Section Header - required - don't modify
|
||||
Use the .Nm macro to refer to your program throughout the man page like such:
|
||||
.Nm
|
||||
Underlining is accomplished with the .Ar macro like this:
|
||||
.Ar underlined text .
|
||||
.Pp \" Inserts a space
|
||||
A list of items with descriptions:
|
||||
.Bl -tag -width -indent \" Begins a tagged list
|
||||
.It item a \" Each item preceded by .It macro
|
||||
Description of item a
|
||||
.It item b
|
||||
Description of item b
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
A list of flags and their descriptions:
|
||||
.Bl -tag -width -indent \" Differs from above in tag removed
|
||||
.It Fl a \"-a flag as a list item
|
||||
Description of -a flag
|
||||
.It Fl b
|
||||
Description of -b flag
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
.\" .Sh ENVIRONMENT \" May not be needed
|
||||
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_1
|
||||
.\" Description of ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_2
|
||||
.\" Description of ENV_VAR_2
|
||||
.\" .El
|
||||
.Sh FILES \" File used or created by the topic of the man page
|
||||
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
|
||||
.It Pa /usr/share/file_name
|
||||
FILE_1 description
|
||||
.It Pa /Users/joeuser/Library/really_long_file_name
|
||||
FILE_2 description
|
||||
.El \" Ends the list
|
||||
.\" .Sh DIAGNOSTICS \" May not be needed
|
||||
.\" .Bl -diag
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .El
|
||||
.Sh SEE ALSO
|
||||
.\" List links in ascending order by section, alphabetically within a section.
|
||||
.\" Please do not reference files that do not exist without filing a bug report
|
||||
.Xr a 1 ,
|
||||
.Xr b 1 ,
|
||||
.Xr c 1 ,
|
||||
.Xr a 2 ,
|
||||
.Xr b 2 ,
|
||||
.Xr a 3 ,
|
||||
.Xr b 3
|
||||
.\" .Sh BUGS \" Document known, unremedied bugs
|
||||
.\" .Sh HISTORY \" Document history if command behaves in a unique manner
|
||||
Reference in New Issue
Block a user