ppup1090.c
Go to the documentation of this file.
1 // ppup1090, a Mode S PlanePlotter Uploader for dump1090 devices.
2 //
3 // Copyright (C) 2013 by Malcolm Robb <Support@ATTAvionics.com>
4 //
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 #include "coaa.h"
31 #include "ppup1090.h"
32 //
33 // ============================= Utility functions ==========================
34 //
35 void sigintHandler(int dummy) {
36  NOTUSED(dummy);
37  signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety
38  Modes.exit = 1; // Signal to threads that we are done
39 }
40 //
41 // =============================== Initialization ===========================
42 //
43 void ppup1090InitConfig(void) {
44 
45  int iErr;
46 
47  // Default everything to zero/NULL
48  memset(&Modes, 0, sizeof(Modes));
49  memset(&ppup1090, 0, sizeof(ppup1090));
50 
51  // Now initialise things that should not be 0/NULL to their defaults
52  Modes.check_crc = 1;
53  Modes.quiet = 1;
54  strcpy(ppup1090.net_input_beast_ipaddr,PPUP1090_NET_OUTPUT_IP_ADDRESS);
55  Modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
56  Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
57  Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
60 
61  if ((iErr = openCOAA()))
62  {
63  fprintf(stderr, "Error 0x%X initialising uploader\n", iErr);
64  exit(1);
65  }
66 }
67 //
68 //=========================================================================
69 //
70 void ppup1090Init(void) {
71 
72  int iErr;
73 
74  // Allocate the various buffers used by Modes
75  if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2)))
76  {
77  fprintf(stderr, "Out of memory allocating data buffer.\n");
78  exit(1);
79  }
80 
81  // Clear the buffers that have just been allocated, just in-case
82  memset(Modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2);
83 
84  // Validate the users Lat/Lon home location inputs
85  if ( (Modes.fUserLat > 90.0) // Latitude must be -90 to +90
86  || (Modes.fUserLat < -90.0) // and
87  || (Modes.fUserLon > 360.0) // Longitude must be -180 to +360
88  || (Modes.fUserLon < -180.0) ) {
89  Modes.fUserLat = Modes.fUserLon = 0.0;
90  } else if (Modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0
91  Modes.fUserLon -= 360.0;
92  }
93  // If both Lat and Lon are 0.0 then the users location is either invalid/not-set, or (s)he's in the
94  // Atlantic ocean off the west coast of Africa. This is unlikely to be correct.
95  // Set the user LatLon valid flag only if either Lat or Lon are non zero. Note the Greenwich meridian
96  // is at 0.0 Lon,so we must check for either fLat or fLon being non zero not both.
97  // Testing the flag at runtime will be much quicker than ((fLon != 0.0) || (fLat != 0.0))
98  Modes.bUserFlags &= ~MODES_USER_LATLON_VALID;
99  if ((Modes.fUserLat != 0.0) || (Modes.fUserLon != 0.0)) {
100  Modes.bUserFlags |= MODES_USER_LATLON_VALID;
101  }
102 
103  // Prepare error correction tables
105 
106  // Setup the uploader - read the user paramaters from the coaa.h header file
109  strcpy(coaa1090.strAuthCode,STR(USER_AUTHCODE));
110  strcpy(coaa1090.strRegNo, STR(USER_REGNO));
112 
113  if ((iErr = initCOAA (coaa1090)))
114  {
115  fprintf(stderr, "Error 0x%X initialising uploader\n", iErr);
116  exit(1);
117  }
118 }
119 //
120 // ================================ Main ====================================
121 //
122 void showHelp(void) {
123  printf(
124 "-----------------------------------------------------------------------------\n"
125 "| ppup1090 RPi Uploader for COAA Planeplotter Ver : "MODES_DUMP1090_VERSION " |\n"
126 "-----------------------------------------------------------------------------\n"
127  "--net-bo-ipaddr <IPv4> TCP Beast output listen IPv4 (default: 127.0.0.1)\n"
128  "--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
129  "--quiet Disable output to stdout. Use for daemon applications\n"
130  "--help Show this help\n"
131  );
132 }
133 //
134 //=========================================================================
135 //
136 int main(int argc, char **argv) {
137  int j, fd;
138  struct client *c;
139 
140  // Set sane defaults
141 
143  signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program)
144 
145  // Parse the command line options
146  for (j = 1; j < argc; j++) {
147  int more = ((j + 1) < argc); // There are more arguments
148 
149  if (!strcmp(argv[j],"--net-bo-port") && more) {
150  Modes.net_input_beast_port = atoi(argv[++j]);
151  } else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) {
152  strcpy(ppup1090.net_input_beast_ipaddr, argv[++j]);
153  } else if (!strcmp(argv[j],"--quiet")) {
154  ppup1090.quiet = 1;
155  } else if (!strcmp(argv[j],"--help")) {
156  showHelp();
157  exit(0);
158  } else {
159  fprintf(stderr, "Unknown or not enough arguments for option '%s'.\n\n", argv[j]);
160  showHelp();
161  exit(1);
162  }
163  }
164 
165  // Initialization
166  ppup1090Init();
167 
168  // Try to connect to the selected ip address and port. We only support *ONE* input connection which we initiate.here.
169  if ((fd = anetTcpConnect(Modes.aneterr, ppup1090.net_input_beast_ipaddr, Modes.net_input_beast_port)) == ANET_ERR) {
170  fprintf(stderr, "Failed to connect to %s:%d\n", ppup1090.net_input_beast_ipaddr, Modes.net_input_beast_port);
171  exit(1);
172  }
173  //
174  // Setup a service callback client structure for a beast binary input (from dump1090)
175  // This is a bit dodgy under Windows. The fd parameter is a handle to the internet
176  // socket on which we are receiving data. Under Linux, these seem to start at 0 and
177  // count upwards. However, Windows uses "HANDLES" and these don't nececeriy start at 0.
178  // dump1090 limits fd to values less than 1024, and then uses the fd parameter to
179  // index into an array of clients. This is ok-ish if handles are allocated up from 0.
180  // However, there is no gaurantee that Windows will behave like this, and if Windows
181  // allocates a handle greater than 1024, then dump1090 won't like it. On my test machine,
182  // the first Windows handle is usually in the 0x54 (84 decimal) region.
183 
184  if (fd >= MODES_NET_MAX_FD) { // Max number of clients reached
185  close(fd);
186  exit(1);
187  }
188 
189  c = (struct client *) malloc(sizeof(*c));
190  c->buflen = 0;
191  c->fd =
192  c->service =
193  Modes.bis = fd;
194  Modes.clients[fd] = c;
195  if (Modes.maxfd < fd) {
196  Modes.maxfd = fd;
197  }
198 
199  // Keep going till the user does something that stops us
200  while (!Modes.exit) {
203  postCOAA ();
204  }
205 
206  // The user has stopped us, so close any socket we opened
207  if (fd != ANET_ERR)
208  {close(fd);}
209 
210  closeCOAA ();
211  pthread_exit(0);
212 }
213 //
214 //=========================================================================
215 //
int openCOAA(void)
void interactiveRemoveStaleAircrafts(void)
Definition: interactive.c:446
void showHelp(void)
Definition: dump1090.c:339
int anetTcpConnect(char *err, char *addr, int port)
Definition: anet.c:181
void ppup1090Init(void)
Definition: ppup1090.c:70
void sigintHandler(int dummy)
Definition: dump1090.c:36
int fd
Definition: dump1090.h:185
double fUserLat
Definition: ppup1090.h:80
#define MODES_ICAO_CACHE_LEN
Definition: dump1090.h:120
int decodeBinMessage(struct client *c, char *p)
Definition: net_io.c:425
struct _coaa1090 coaa1090
int exit
Definition: dump1090.h:237
#define MODES_USER_LATITUDE_DFLT
Definition: dump1090.h:75
void modesInitErrorInfo()
Definition: mode_s.c:234
void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *))
Definition: net_io.c:759
int service
Definition: dump1090.h:186
#define MODES_USER_LONGITUDE_DFLT
Definition: dump1090.h:76
int fd
Definition: dump1090.h:233
#define MODES_INTERACTIVE_DISPLAY_TTL
Definition: dump1090.h:163
#define NOTUSED(V)
Definition: ppup1090.h:63
int initCOAA(struct _coaa1090 coaa1090)
char strVersion[16]
Definition: ppup1090.h:84
int main(int argc, char *argv[])
Definition: DBSync.cc:58
struct @0 Modes
char strAuthCode[16]
Definition: ppup1090.h:82
#define STR(x)
Definition: ppup1090.h:66
char strRegNo[16]
Definition: ppup1090.h:83
struct @1 ppup1090
void ppup1090InitConfig(void)
Definition: ppup1090.c:43
#define MODES_INTERACTIVE_DELETE_TTL
Definition: dump1090.h:162
#define MODES_NET_MAX_FD
Definition: dump1090.h:165
void postCOAA(void)
#define MODES_DUMP1090_VERSION
Definition: dump1090.h:40
#define MODES_USER_LATLON_VALID
Definition: dump1090.h:125
#define MODES_NET_OUTPUT_BEAST_PORT
Definition: dump1090.h:170
int closeCOAA(void)
double fUserLon
Definition: ppup1090.h:81
int buflen
Definition: dump1090.h:187
#define PPUP1090_NET_OUTPUT_IP_ADDRESS
Definition: ppup1090.h:61
#define ANET_ERR
Definition: anet.h:35

, generated on Tue Sep 26 2023.