main.c - acarsdec - an ACARS decoder
 (HTM) git clone git://r-36.net/acarsdec
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) 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