acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | README

main.c (7142B)


      1 /*
      2  *  Copyright (c) 2007 by Thierry Leconte (F4DWV)
      3  *            (c) 2010-12 by Christoph Lohmann <20h@r-36.net>
      4  *
      5  *      $Id: main.c,v 1.5 2007/04/22 16:14:41 f4dwv Exp $
      6  *
      7  *   This code is free software; you can redistribute it and/or modify
      8  *   it under the terms of the GNU Library General Public License version 2
      9  *   published by the Free Software Foundation.
     10  *
     11  *   This program is distributed in the hope that it will be useful,
     12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  *   GNU Library General Public License for more details.
     15  *
     16  *   You should have received a copy of the GNU Library General Public
     17  *   License along with this library; if not, write to the Free Software
     18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19  *
     20  */
     21 
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <unistd.h>
     25 #include <string.h>
     26 #include <time.h>
     27 
     28 #include "version.h"
     29 #include "acarsdec.h"
     30 
     31 extern int optind, opterr;
     32 extern char *optarg;
     33 
     34 #define RED      "\033[0;31m"        /* 0 -> normal ;  31 -> red */
     35 #define CYAN     "\033[1;36m"        /* 1 -> bold ;  36 -> cyan */
     36 #define GREEN    "\033[1;32m"        /* 1 -> bold ;  32 -> green */
     37 #define YELLOW   "\033[0;33m"        /* 0 -> normal ;  33 -> yellow */
     38 #define BLUE     "\033[1;34m"        /* 1 -> bold ;  34 -> blue */
     39 
     40 #define BLACK    "\033[0;30m"
     41 #define BROWN    "\033[0;33m"
     42 #define MAGENTA  "\033[7;35m"        /* 7 -> inverted; 35 -> magenta */
     43 #define GRAY     "\033[0;37m"
     44 
     45 #define NONE     "\033[0m"           /* to flush the previous property */
     46 
     47 
     48 static void usage(void)
     49 {
     50 	fprintf(stderr, "%s\n", version);
     51 	fprintf(stderr, "Usage: acarsdec [-vep][-LR][-s noport] -d "
     52 			"alsapcmdevice | -f sndfile | -t\n");
     53 	fprintf(stderr, " -f sndfile :\t\tdecode from file sndfile "
     54 			"(ie: a .wav file)\n");
     55 	fprintf(stderr, " -d alsapcmdevice :\tdecode from soundcard "
     56 			"input alsapcmdevice (ie: hw:0,0)\n");
     57 	fprintf(stderr, " -t :\t\t\tread from stdin.\n");
     58 	fprintf(stderr, " [-v] :\t\t\tbe verbose.\n");
     59 	fprintf(stderr, " [-c] :\t\t\tcolorful output.\n");
     60 	fprintf(stderr, " [-p] :\t\t\toutput should be parseable protocol.\n");
     61 	fprintf(stderr, " [-e] :\t\t\tturn on debugging\n");
     62 	fprintf(stderr, " [-LR] :\t\tdisable left or right channel "
     63 			"decoding of stereo signal\n");
     64 	fprintf(stderr, " [-s noport ] :\t\tact as an APRS local server, "
     65 			"on port : noport\n");
     66 	fprintf(stderr, "Input could be mono or stereo but with 48Khz "
     67 			"sampling frequency.\nIf stereo, acarsdec will "
     68 			"demod the 2 channels independantly (if no L ou "
     69 			"R options specified)\n\n");
     70 	exit(1);
     71 }
     72 
     73 void print_mesg(msg_t *msg, int colored, int messgnumb)
     74 {
     75 	time_t t;
     76 	struct tm *tmp;
     77 	char pos[128];
     78 	int i;
     79 
     80 	for (i = 0; i < msg->txtlen; i++) {
     81 		if (msg->txt[i] < ' ' && msg->txt[i] != '\r'
     82 				&& msg->txt[i] != '\n') {
     83 			msg->txt[i] = ' ';
     84 		}
     85 	}
     86 
     87 	if (colored) {
     88 		printf("ACARS mode: %s%c%s", RED, msg->mode, NONE);
     89 		printf(" Aircraft reg: %s%s%s\n", GREEN,msg->addr,NONE);
     90 		printf("Message label: %s%s%s", CYAN, msg->label, NONE);
     91 		printf(" Block id: %s%d%s", RED, (int)msg->bid, NONE);
     92 		printf(" Msg. no: %s%s%s\n", BLUE, msg->no, NONE);
     93 		printf("Flight id: %s%s%s\n", MAGENTA, msg->fid, NONE);
     94 		printf("Message content:-\n%s%s%s", YELLOW, msg->txt, NONE);
     95 		if (posconv(msg->txt, msg->label, pos)==0) {
     96 			printf("\n%sAPRS : Addr:%s Fid:%s Lbl:%s pos:%s%s\n",
     97 				RED, msg->addr, msg->fid, msg->label, pos, NONE);
     98 		}
     99 	} else {
    100 		printf("ACARS mode: %c", msg->mode);
    101 		printf(" Aircraft reg: %s\n", msg->addr);
    102 		printf("Message label: %s", msg->label);
    103 		printf(" Block id: %d", (int) msg->bid);
    104 		printf(" Msg. no: %s\n", msg->no);
    105 		printf("Flight id: %s\n", msg->fid);
    106 		printf("Message content:-\n%s", msg->txt);
    107 		if (posconv(msg->txt, msg->label, pos)==0) {
    108 			printf("\nAPRS : Addr:%s Fid:%s Lbl:%s pos:%s\n",
    109 				msg->addr, msg->fid, msg->label, pos);
    110 		}
    111 	}
    112 
    113 	t = time(NULL);
    114 	tmp = gmtime(&t);
    115 	printf("\n[%5d]-------------------------------------"
    116 		"--------------[%02d/%02d/%04d %02d:%02d:%02d]\n\n",
    117 		messgnumb,
    118 	        tmp->tm_mday, tmp->tm_mon + 1, tmp->tm_year + 1900,
    119 	        tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
    120 	fflush(stdout);
    121 }
    122 
    123 void print_proto(msg_t *msg)
    124 {
    125 	time_t t;
    126 	struct tm *tmp;
    127 	char pos[128];
    128 	char timestamp[128];
    129 
    130 	printf("MESG\n");
    131 	printf("MODE: %c\n", msg->mode);
    132 	printf("REG: %s\n", msg->addr);
    133 	printf("LABEL: %s\n", msg->label);
    134 	printf("BLKID: %d\n", (int) msg->bid);
    135 	printf("MSGNO: %s\n", msg->no);
    136 	printf("FLIGHTID: %s\n", msg->fid);
    137 	printf("CONTENTLENGTH: %d\n", msg->txtlen);
    138 	printf("CONTENT:\n");
    139 	fwrite(msg->txt, msg->txtlen, 1, stdout);
    140 	printf("\n.\n");
    141 
    142 	if (posconv(msg->txt, msg->label, pos) == 0) {
    143 		printf("APRS-ADDR: %s\n", msg->addr);
    144 		printf("APRS-FID: %s\n", msg->fid);
    145 		printf("APRS-LABEL: %s\n", msg->label);
    146 		printf("APRS-POS: %s\n", pos);
    147 	}
    148 	t = time(NULL);
    149 	tmp = gmtime(&t);
    150 	strftime(timestamp, sizeof(timestamp) - 1,
    151 		"%FT%T+00:00", tmp);
    152 	printf("TIMESTAMP: %s\n", timestamp);
    153 	printf("END MESG\n\n");
    154 	fflush(stdout);
    155 }
    156 
    157 void do_output(int type, msg_t *msg, int colored, int messgnumb)
    158 {
    159 
    160 	if(type & OUT_NET)
    161 		send_mesg(msg);
    162 	if(type & OUT_PRINT)
    163 		print_mesg(msg,colored,messgnumb);
    164 	if(type & OUT_PROTO)
    165 		print_proto(msg);
    166 }
    167 
    168 int main(int argc, char **argv)
    169 {
    170 	int c;
    171 	unsigned char r[2];
    172 	msg_t msg[2];
    173 	int nbit[2] = {0, 0};
    174 	int nrbit[2] = {8, 8};
    175 	int nbch = 0;
    176 	int esel[2] = {1, 1};
    177 	short port = 0;
    178 	int debug = 0;
    179 	int output = 0;
    180 	int i;
    181 	int colored = 0;
    182 	int messgnumb = 0;
    183 
    184 	while ((c = getopt(argc, argv, "cptevd:f:RLs:")) != EOF) {
    185 		switch (c) {
    186 		case 'd':
    187 			nbch = initsample(optarg, IN_ALSA);
    188 			break;
    189 		case 'f':
    190 			nbch = initsample(optarg, IN_FILE);
    191 			break;
    192 		case 't':
    193 			nbch = initsample("stdin", IN_STDIN);
    194 			break;
    195 		case 'L':
    196 			esel[0] = 0;
    197 			break;
    198 		case 'R':
    199 			esel[1] = 0;
    200 			break;
    201 		case 's':
    202 			port=atoi(optarg);
    203 			output |= OUT_NET;
    204 			break;
    205 		case 'v':
    206 			output |= OUT_PRINT;
    207 			break;
    208 		case 'p':
    209 			output |= OUT_PROTO;
    210 			break;
    211 		case 'e':
    212 			debug++;
    213 			break;
    214 		case 'c':
    215 			colored = 1;
    216 			break;
    217 		default:
    218 			usage();
    219 			exit(1);
    220 		}
    221 	}
    222 
    223 	if (output == 0)
    224 		output = OUT_PRINT;
    225 
    226 	if (nbch == 0) {
    227 		usage();
    228 		exit(1);
    229 	}
    230 
    231 	if (debug)
    232 		fprintf(stderr, "Output = %d; channels = %d\n", output, nbch);
    233 
    234 	if (port) {
    235 		if (init_serv(port))
    236 			exit(1);
    237 		if (debug)
    238 			fprintf(stderr, "Server initialized.\n");
    239 	}
    240 
    241 	/* main loop */
    242 	init_bits();
    243 	init_mesg();
    244 
    245 	if(debug)
    246 		fprintf(stderr, "Starting receive loop.\n");
    247 	do {
    248 		short sample[4096];
    249 		int ind, len;
    250 
    251 		len = getsample(sample, 4096);
    252 		if (len <= 0)
    253 			break;
    254 
    255 		for (ind = 0; ind < len;) {
    256 			for (i = 0; i < nbch; i++, ind++) {
    257 				if (esel[i]) {
    258 					nbit[i] += getbit(sample[ind], &r[i],
    259 							(i? 1 : 0));
    260 					if (nbit[i] >= nrbit[i]) {
    261 						nrbit[i] = getmesg(r[i],
    262 							       &msg[i], (i? 1 : 0));
    263 						nbit[i] = 0;
    264 						if (nrbit[i] == 0) {
    265 							do_output(output,
    266 								&msg[i], colored, ++messgnumb);
    267 							nrbit[i] = 8;
    268 						}
    269 					}
    270 				}
    271 			}
    272 		}
    273 	} while (1);
    274 
    275 
    276 	if(port)
    277 		end_serv();
    278 
    279 	endsample();
    280 
    281 	exit(0);
    282 }
    283