Skip to content

Commit

Permalink
treewide: first step for making outputs independent
Browse files Browse the repository at this point in the history
This commit enables the use of multiple concurrent outputs, using the
following syntax:

acarsdec --output format:destination:parameters [--output ...]

Where "format" is one of:
- "oneline" for single line text decoding
- "full" for full text decoding
- "monitor" for live decoding
- "pp" for PlanePlotter
- "native" for Acarsdec native format
With CJSON support enabled:
- "json" for JSON output
- "routejson" for flight route output in JSON format

and "destination" is one of:
- "file" for file (including stdout) output
- "udp" for network output over UDP
With MQTT support enabled:
- "mqtt" for MQTT output

Not all combinations of format and destination are valid, acarsdec will
complain if an invalid combination is chosen.

params are described in respective source file (TODO: update usage())

Fixes: TLeconte#76
  • Loading branch information
f00b4r0 committed Aug 13, 2024
1 parent 9cecbdd commit 11ddc22
Show file tree
Hide file tree
Showing 11 changed files with 664 additions and 407 deletions.
1 change: 1 addition & 0 deletions acars.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <string.h>
#include <math.h>
#include "acarsdec.h"
#include "output.h"

#define SYN 0x16
#define SOH 0x01
Expand Down
86 changes: 11 additions & 75 deletions acarsdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
#include <libacars/version.h>
#endif
#include "acarsdec.h"
#include "output.h"

extern void build_label_filter(char *arg);

runtime_t R = {
.outtype = OUTTYPE_STD,
.netout = NETLOG_NONE,
.mdly = 600,
.rateMult = 160,
.lnaState = 2,
Expand All @@ -48,13 +48,10 @@ static void usage(void)
#ifdef HAVE_LIBACARS
fprintf(stderr, "(libacars %s)\n", LA_VERSION);
#endif
fprintf(stderr, "\nUsage: acarsdec [-o lv] [-t time] [-A] [-b 'labels,..'] [-e] [-i station_id] [-n|-j|-N ipaddr:port] [-l logfile [-H|-D]]");
fprintf(stderr, "\nUsage: acarsdec [-t time] [-A] [-b 'labels,..'] [-e] [-i station_id]");
#ifdef HAVE_LIBACARS
fprintf(stderr, " [--skip-reassembly] ");
#endif
#ifdef WITH_MQTT
fprintf(stderr, " [ -M mqtt_url [-T mqtt_topic] | [-U mqtt_user | -P mqtt_passwd]] |");
#endif
#ifdef WITH_ALSA
fprintf(stderr, " -a alsapcmdevice |");
#endif
Expand Down Expand Up @@ -82,27 +79,10 @@ static void usage(void)
" -A\t\t\t: don't output uplink messages (ie : only aircraft messages)\n"
" -e\t\t\t: don't output empty messages (ie : _d,Q0, etc ...)\n"
" -b filter\t\t: filter output by label (ex: -b \"H1:Q0\" : only output messages with label H1 or Q0)\n"
" -o lv\t\t\t: output format : 0 : no log, 1 : one line by msg, 2 : full (default) , 3 : monitor"
#ifdef HAVE_CJSON
", 4 : msg JSON, 5 : route JSON"
#endif
"\n"
" -t time\t\t: set forget time (TTL) in seconds for monitor mode (default=600s)\n"
" -l logfile\t\t: append log messages to logfile (Default : stdout).\n"
" -H\t\t\t: rotate log file once every hour\n"
" -D\t\t\t: rotate log file once every day\n"
"\n"
" -n ipaddr:port\t\t: send acars messages to addr:port on UDP in planeplotter compatible format\n"
" -N ipaddr:port\t\t: send acars messages to addr:port on UDP in acarsdec native format\n"
#ifdef HAVE_CJSON
" -j ipaddr:port\t\t: send acars messages to addr:port on UDP in acarsdec json format\n"
#ifdef WITH_MQTT
" -M mqtt_url\t\t: Url of MQTT broker\n"
" -T mqtt_topic\t\t: Optionnal MQTT topic (default : acarsdec/${station_id})\n"
" -U mqtt_user\t\t: Optional MQTT username\n"
" -P mqtt_passwd\t\t: Optional MQTT password\n"
#endif /* WITH_MQTT */
#endif /* HAVE_CJSON */
"\n");

#ifdef WITH_ALSA
Expand Down Expand Up @@ -170,6 +150,7 @@ int main(int argc, char **argv)
{ "verbose", no_argument, NULL, 'v' },
{ "skip-reassembly", no_argument, NULL, 1 },
{ "antenna", required_argument, NULL, 2 },
{ "output", required_argument, NULL, 3 },
{ NULL, 0, NULL, 0 }
};
char sys_hostname[HOST_NAME_MAX + 1];
Expand All @@ -180,14 +161,14 @@ int main(int argc, char **argv)
R.idstation = strdup(sys_hostname);

res = 0;
while ((c = getopt_long(argc, argv, "HDvarfdsRo:t:g:m:Aep:n:N:j:l:c:i:L:G:b:M:P:U:T:B:", long_opts, NULL)) != EOF) {
while ((c = getopt_long(argc, argv, "HDvarfdsRt:g:m:Aep:c:i:L:G:b:B:", long_opts, NULL)) != EOF) {
switch (c) {
case 3:
setup_output(optarg);
break;
case 'v':
R.verbose = 1;
break;
case 'o':
R.outtype = atoi(optarg);
break;
case 't':
R.mdly = atoi(optarg);
break;
Expand Down Expand Up @@ -270,49 +251,13 @@ int main(int argc, char **argv)
res = initAirspy(argv, optind);
R.inmode = 4;
break;
#endif
#ifdef WITH_MQTT
case 'M':
if (R.mqtt_nburls < 15) {
R.mqtt_urls[R.mqtt_nburls] = strdup(optarg);
R.mqtt_nburls++;
R.mqtt_urls[R.mqtt_nburls] = NULL;
R.netout = NETLOG_MQTT;
}
break;
case 'U':
R.mqtt_user = strdup(optarg);
break;
case 'P':
R.mqtt_passwd = strdup(optarg);
break;
case 'T':
R.mqtt_topic = strdup(optarg);
break;
#endif
case 'n':
R.Rawaddr = optarg;
R.netout = NETLOG_PLANEPLOTTER;
break;
case 'N':
R.Rawaddr = optarg;
R.netout = NETLOG_NATIVE;
break;
#ifdef HAVE_CJSON
case 'j':
R.Rawaddr = optarg;
R.netout = NETLOG_JSON;
break;
#endif
case 'A':
R.airflt = 1;
break;
case 'e':
R.emptymsg = 1;
break;
case 'l':
R.logfilename = optarg;
break;
case 'H':
R.hourly = 1;
break;
Expand Down Expand Up @@ -342,18 +287,10 @@ int main(int argc, char **argv)

build_label_filter(lblf);

res = initOutput(R.logfilename, R.Rawaddr);
res = initOutputs();
if (res)
errx(res, "Unable to init output\n");

#ifdef WITH_MQTT
if (R.netout == NETLOG_MQTT) {
res = MQTTinit(R.mqtt_urls, R.idstation, R.mqtt_topic, R.mqtt_user, R.mqtt_passwd);
if (res)
errx(res, "Unable to init MQTT\n");
}
#endif

#ifdef WITH_SOAPY
if (R.antenna) {
if (R.verbose)
Expand Down Expand Up @@ -444,8 +381,7 @@ int main(int argc, char **argv)

deinitAcars();

#ifdef WITH_MQTT
MQTTend();
#endif
exitOutputs();

exit(res);
}
48 changes: 15 additions & 33 deletions acarsdec.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/

#ifndef acarsdec_h
#define acarsdec_h

#include <sys/time.h>
#include <time.h>
#include <pthread.h>
Expand All @@ -33,18 +37,7 @@

#define INTRATE 12500

#define NETLOG_NONE 0
#define NETLOG_PLANEPLOTTER 1
#define NETLOG_NATIVE 2
#define NETLOG_JSON 3
#define NETLOG_MQTT 4

#define OUTTYPE_NONE 0
#define OUTTYPE_ONELINE 1
#define OUTTYPE_STD 2
#define OUTTYPE_MONITOR 3
#define OUTTYPE_JSON 4
#define OUTTYPE_ROUTEJSON 5
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

typedef float sample_t;

Expand Down Expand Up @@ -122,14 +115,20 @@ typedef struct {
#endif
} acarsmsg_t;

typedef struct output_s {
enum { FMT_ONELINE = 1, FMT_FULL, FMT_MONITOR, FMT_PP, FMT_NATIVE, FMT_JSON, FMT_ROUTEJSON } fmt;
enum { DST_FILE = 1, DST_UDP, DST_MQTT } dst;
void *params;
void *priv;
struct output_s *next;
} output_t;

typedef struct {
channel_t *channels;
unsigned int nbch;

int inmode;
int verbose;
int outtype;
int netout;
int airflt;
int emptymsg;
int mdly;
Expand All @@ -153,22 +152,11 @@ typedef struct {
int freq;
#endif

#ifdef WITH_MQTT
char *mqtt_urls[16];
int mqtt_nburls;
char *mqtt_topic;
char *mqtt_user;
char *mqtt_passwd;
#endif

char *Rawaddr;
char *logfilename;
output_t *outputs;
} runtime_t;

extern runtime_t R;

extern int initOutput(char *, char *);

#ifdef WITH_ALSA
extern int initAlsa(char **argv, int optind);
extern int runAlsaSample(void);
Expand Down Expand Up @@ -198,12 +186,6 @@ extern int runSoapySample(void);
extern int runSoapyClose(void);
#endif

#ifdef WITH_MQTT
extern int MQTTinit(char **urls, char *client_id, char *topic, char *user, char *passwd);
extern int MQTTsend(char *msgtxt);
extern void MQTTend();
#endif

extern int initRaw(char **argv, int optind);
extern int runRawSample(void);
extern int initMsk(channel_t *);
Expand All @@ -215,4 +197,4 @@ extern int deinitAcars(void);

extern int DecodeLabel(acarsmsg_t *msg, oooi_t *oooi);

extern void outputmsg(const msgblk_t *);
#endif /* acarsdec_h */
Loading

0 comments on commit 11ddc22

Please sign in to comment.