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