acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | 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