serv.c - acarsdec - an ACARS decoder
 (HTM) git clone git://r-36.net/acarsdec
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
       serv.c (7637B)
       ---
            1 /*
            2  *  Copyright (c) 2007 by Thierry Leconte (F4DWV)
            3  *                        (c) 2010 by Christoph Lohmann <20h@r-36.net>
            4  *
            5  *          $Id: serv.c,v 1.2 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 <stdlib.h>
           23 #include <unistd.h>
           24 #include <stdio.h>
           25 #include <string.h>
           26 #include <sys/types.h>
           27 #include <sys/socket.h>
           28 #include <netinet/in.h>
           29 #include <errno.h>
           30 
           31 #include "acarsdec.h"
           32 
           33 static int sa, sc;
           34 
           35 int init_serv(short port)
           36 {
           37         struct sockaddr_in locaddr, remaddr;
           38         socklen_t len;
           39         char c;
           40         int res;
           41 
           42         sa = socket(PF_INET, SOCK_STREAM, 0);
           43         if (sa < 0) {
           44                 fprintf(stderr, "socket : %s\n", strerror(errno));
           45                 return -1;
           46         }
           47 
           48         res = 1;
           49         res = setsockopt(sa, SOL_SOCKET, SO_REUSEADDR, &res, sizeof(res));
           50         if (res) {
           51                 fprintf(stderr, "reuseaddr : %s\n", strerror(errno));
           52                 return -1;
           53         }
           54 
           55         memset(&locaddr, 0, sizeof(locaddr));
           56         locaddr.sin_family = AF_INET;
           57         locaddr.sin_port = htons(port);
           58         locaddr.sin_addr.s_addr = htonl(INADDR_ANY);
           59 
           60         len = sizeof(locaddr);
           61         res = bind(sa, (struct sockaddr *) &locaddr, len);
           62         if (res) {
           63                 fprintf(stderr, "bind : %s\n", strerror(errno));
           64                 return -1;
           65         }
           66 
           67         res = listen(sa, 1);
           68         if (res) {
           69                 fprintf(stderr, "listen : %s\n", strerror(errno));
           70                 return -1;
           71         }
           72 
           73         memset(&remaddr, 0, sizeof(remaddr));
           74         len = sizeof(remaddr);
           75         sc = accept(sa, (struct sockaddr *) &remaddr, &len);
           76         if (sc < 0) {
           77                 fprintf(stderr, "accept : %s\n", strerror(errno));
           78                 return -1;
           79         }
           80 
           81         do {
           82                 res = read(sc, &c, 1);
           83         } while (res == 1 && c != '\n');
           84 
           85 
           86         return 0;
           87 }
           88 
           89 
           90 /* convert ACARS position reports to APRS position */
           91 static void toaprs(int la, char lac, int ln, char lnc, int prec, char *out)
           92 {
           93         int lad, lnd;
           94         float lam, lnm;
           95 
           96         lad = la / 10000;
           97         lnd = ln / 10000;
           98         lam = (float) (la - (lad * 10000)) * 60.0 / 10000.0;
           99         lnm = (float) (ln - (lnd * 10000)) * 60.0 / 10000.0;
          100 
          101         switch (prec) {
          102         case 0:
          103                 sprintf(out, "%02d%02.0f.  %c/%03d%02.0f.  %c^",
          104                                 lad, lam, lac, lnd, lnm, lnc);
          105                 break;
          106         case 1:
          107                 sprintf(out, "%02d%04.1f %c/%03d%04.1f %c^",
          108                                 lad, lam, lac, lnd, lnm, lnc);
          109                 break;
          110         case 2:
          111         default:
          112                 sprintf(out, "%02d%05.2f%c/%03d%05.2f%c^",
          113                                 lad, lam, lac, lnd, lnm, lnc);
          114                 break;
          115         }
          116 }
          117 
          118 int posconv(char *txt, unsigned char *label, char *pos)
          119 {
          120         char lac, lnc;
          121         int la, ln;
          122         char las[7], lns[7];
          123         int n;
          124         char *p;
          125 
          126         /*try different heuristics */
          127 
          128         n = sscanf(txt, "#M1BPOS%c%05d%c%063d,", &lac, &la, &lnc, &ln);
          129         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          130                 la *= 10;
          131                 ln *= 10;
          132                 toaprs(la, lac, ln, lnc, 1, pos);
          133                 return 0;;
          134         }
          135         n = sscanf(txt, "#M1AAEP%c%06d%c%07d", &lac, &la, &lnc, &ln);
          136         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          137                 toaprs(la, lac, ln, lnc, 2, pos);
          138                 return 0;;
          139         }
          140 
          141         if (strncmp(txt, "#M1B", 4) == 0) {
          142                 if ((p = strstr(txt, "/FPO")) != NULL) {
          143                         n = sscanf(p, "/FPO%c%05d%c%06d", &lac, &la, &lnc, &ln);
          144                         if (n == 4 && (lac == 'N' || lac == 'S')
          145                         && (lnc == 'E' || lnc == 'W')) {
          146                                 la *= 10;
          147                                 ln *= 10;
          148                                 toaprs(la, lac, ln, lnc, 1, pos);
          149                                 return 0;;
          150                         }
          151                 }
          152                 if ((p = strstr(txt, "/PS")) != NULL) {
          153                         n = sscanf(p, "/PS%c%05d%c%06d", &lac, &la, &lnc, &ln);
          154                         if (n == 4 && (lac == 'N' || lac == 'S')
          155                         && (lnc == 'E' || lnc == 'W')) {
          156                         la *= 10;
          157                         ln *= 10;
          158                         toaprs(la, lac, ln, lnc, 1, pos);
          159                         return 0;;
          160                         }
          161                 }
          162         }
          163 
          164         n = sscanf(txt, "FST01%*8s%c%06d%c%07d", &lac, &la, &lnc, &ln);
          165         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          166                 toaprs(la, lac, ln, lnc, 2, pos);
          167                 return 0;;
          168         }
          169 
          170         n = sscanf(txt, "(2%c%5c%c%6c", &lac, las, &lnc, lns);
          171         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          172                 las[5] = 0;
          173                 lns[6] = 0;
          174                 la = 10 * atoi(las);
          175                 ln = 10 * atoi(lns);
          176                 toaprs(la, lac, ln, lnc, 1, pos);
          177                 return 0;;
          178         }
          179 
          180         n = sscanf(txt, "(:2%c%5c%c%6c", &lac, las, &lnc, lns);
          181         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          182                 las[5] = 0;
          183                 lns[6] = 0;
          184                 la = 10 * atoi(las);
          185                 ln = 10 * atoi(lns);
          186                 toaprs(la, lac, ln, lnc, 1, pos);
          187                 return 0;;
          188         }
          189 
          190 
          191         n = sscanf(txt, "(2%*4s%c%5c%c%6c", &lac, las, &lnc, lns);
          192         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          193                 las[5] = 0;
          194                 lns[6] = 0;
          195                 la = 10 * atoi(las);
          196                 ln = 10 * atoi(lns);
          197                 toaprs(la, lac, ln, lnc, 1, pos);
          198                 return 0;;
          199         }
          200 
          201         n = sscanf(txt, "LAT %c%3c.%3c/LON %c%3c.%3c", &lac, las, &(las[3]),
          202                    &lnc, lns, &(lns[3]));
          203         if (n == 6 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          204                 las[6] = 0;
          205                 lns[6] = 0;
          206                 la = 10 * atoi(las);
          207                 ln = 10 * atoi(lns);
          208                 toaprs(la, lac, ln, lnc, 1, pos);
          209                 return 0;;
          210         }
          211 
          212 
          213         n = sscanf(txt, "#DFB(POS-%*6s-%04d%c%05d%c/", &la, &lac, &ln, &lnc);
          214         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          215                 la *= 100;
          216                 ln *= 100;
          217                 toaprs(la, lac, ln, lnc, 0, pos);
          218                 return 0;;
          219         }
          220 
          221         n = sscanf(txt, "#DFB*POS\a%*8s%c%04d%c%05d/", &lac, &la, &lnc, &ln);
          222         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          223                 la *= 100;
          224                 ln *= 100;
          225                 toaprs(la, lac, ln, lnc, 0, pos);
          226                 return 0;;
          227         }
          228 
          229         n = sscanf(txt, "POS%c%05d%c%06d,", &lac, &la, &lnc, &ln);
          230         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          231                 la *= 10;
          232                 ln *= 10;
          233                 toaprs(la, lac, ln, lnc, 1, pos);
          234                 return 0;;
          235         }
          236 
          237         n = sscanf(txt, "POS%*2s,%c%05d%c%06d,", &lac, &la, &lnc, &ln);
          238         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          239                 la *= 10;
          240                 ln *= 10;
          241                 toaprs(la, lac, ln, lnc, 1, pos);
          242                 return 0;;
          243         }
          244 
          245         n = sscanf(txt, "RCL%*2s,%c%05d%c%06d,", &lac, &la, &lnc, &ln);
          246         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          247                 la *= 10;
          248                 ln *= 10;
          249                 toaprs(la, lac, ln, lnc, 1, pos);
          250                 return 0;;
          251         }
          252 
          253         n = sscanf(txt, "TWX%*2s,%c%05d%c%06d,", &lac, &la, &lnc, &ln);
          254         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          255                 la *= 10;
          256                 ln *= 10;
          257                 toaprs(la, lac, ln, lnc, 1, pos);
          258                 return 0;;
          259         }
          260 
          261         n = sscanf(txt, "CLA%*2s,%c%05d%c%06d,", &lac, &la, &lnc, &ln);
          262         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          263                 la *= 10;
          264                 ln *= 10;
          265                 toaprs(la, lac, ln, lnc, 1, pos);
          266                 return 0;;
          267         }
          268 
          269         n = sscanf(txt, "%c%05d/%c%06d,", &lac, &la, &lnc, &ln);
          270         if (n == 4 && (lac == 'N' || lac == 'S') && (lnc == 'E' || lnc == 'W')) {
          271                 la *= 10;
          272                 ln *= 10;
          273                 toaprs(la, lac, ln, lnc, 1, pos);
          274                 return 0;;
          275         }
          276 
          277         return 1;
          278 }
          279 
          280 int send_mesg(msg_t * msg)
          281 {
          282         char apstr[512];
          283         char txt[512];
          284         char pos[64];
          285         unsigned char *ind;
          286 
          287         if(msg->label[0]=='_' && msg->label[1]==0x7f)
          288                 return 0;
          289 
          290         strcpy(txt,msg->txt);
          291         for(ind = (unsigned char *)&txt; *ind != 0 ;ind++) {
          292                 if(*ind==0x0a || *ind == 0x0d) *ind=' ';
          293         }
          294 
          295         ind = msg->addr;
          296         while (*ind == '.' && *ind != 0)
          297                 ind++;
          298 
          299         if (posconv(msg->txt, msg->label, pos)) {
          300                 sprintf(apstr, "%s>ACARS:>Fid:%s Lbl:%s %s\n",
          301                                 ind, msg->fid,msg->label,txt);
          302         } else {
          303                 sprintf(apstr, "%s>ACARS:!%sFid:%s Lbl:%s %s\n",
          304                                 ind, pos,msg->fid,msg->label,txt);
          305         }
          306 
          307         write(sc, apstr, strlen(apstr));
          308 
          309         return 0;
          310 }
          311 
          312 
          313 void end_serv(void)
          314 {
          315         close(sc);
          316         close(sa);
          317 }
          318