1 /*
2  * Tlf - contest logging program for amateur radio operators
3  * Copyright (C) 2001-2002-2003 Rein Couperus <pa0rct@amsat.org>
4  * 		 2013 		Fred DH5FS
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <netdb.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <syslog.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <arpa/inet.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 
34 #include "err_utils.h"
35 #include "lancode.h"
36 #include "tlf.h"
37 #include "tlf_curses.h"
38 
39 
40 int lan_socket_descriptor;
41 struct sockaddr_in lan_sin;
42 int lan_bind_rc, lan_close_rc;
43 ssize_t lan_recv_rc;
44 long lan_save_file_flags;
45 char lan_recv_message[256];
46 char lan_message[256];
47 char lan_logline[256];
48 unsigned int lan_sin_len;
49 //--------------------------------------
50 int bc_socket_descriptor[MAXNODES];
51 ssize_t bc_sendto_rc;
52 int bc_close_rc;
53 int cl_send_inhibit = 0;
54 char lanbuffer[255];
55 struct sockaddr_in bc_address[MAXNODES];
56 struct hostent *bc_hostbyname[MAXNODES];
57 /* host names and UDP ports to send notifications to */
58 char bc_hostaddress[MAXNODES][16];
59 char bc_hostservice[MAXNODES][16] = {
60     [0 ... MAXNODES - 1] = { [0 ... 15] = 0 }
61 };
62 char sendbuffer[256];
63 int nodes = 0;
64 int node;
65 int send_error_limit[MAXNODES];
66 //--------------------------------------
67 /* default port to listen for incomming packets and to send packet to */
68 char default_lan_service[16] = "6788";
69 /* lan port parsed from config */
70 int lan_port = 6788;
71 
72 int lan_active = 0;
73 int send_error[MAXNODES];
74 int lan_mutex = 0;
75 int send_packets[MAXNODES];
76 int recv_error;
77 int recv_packets;
78 int buflen;
79 char talkarray[5][62];
80 freq_t node_frequencies[MAXNODES];
81 int lanqsos;
82 char lastqsonr[5];
83 int highqsonr;
84 int landebug = 0;
85 long lantime;
86 long timecorr;
87 int time_master;
88 char thisnode = 'A'; 		/*  start with 'A' if not defined in
89 				    logcfg.dat */
90 
91 //---------------------end lan globals --------------
92 
resolveService(const char * service)93 int resolveService(const char *service) {
94     struct servent *service_ent;
95     service_ent = getservbyname(service, "udp");
96     int port = 0;
97     if (service_ent != NULL) {
98 	port = ntohs(service_ent->s_port);
99     } else if (strlen(service) > 0) {
100 	port = atoi(service);
101     }
102     if (port == 0) {
103 	port = atoi(default_lan_service);
104     }
105     return port;
106 }
107 
lanrecv_init(void)108 int lanrecv_init(void) {
109     if (lan_active == 0)
110 	return (1);
111 
112     sprintf(default_lan_service, "%d", lan_port);
113     bzero(&lan_sin, sizeof(lan_sin));
114     lan_sin.sin_family = AF_INET;
115     lan_sin.sin_addr.s_addr = htonl(INADDR_ANY);
116     lan_sin.sin_port = htons(resolveService(default_lan_service));
117     lan_sin_len = sizeof(lan_sin);
118 
119     lan_socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
120     if (lan_socket_descriptor == -1) {
121 	syslog(LOG_ERR, "%s\n", "LAN: socket");
122 	return (-1);
123     }
124 
125     lan_bind_rc =
126 	bind(lan_socket_descriptor, (struct sockaddr *) &lan_sin,
127 	     sizeof(lan_sin));
128     if (lan_bind_rc == -1) {
129 	syslog(LOG_ERR, "%s\n", "LAN: bind");
130 	return (-2);
131     }
132 
133     lan_save_file_flags = fcntl(lan_socket_descriptor, F_GETFL);
134     lan_save_file_flags |= O_NONBLOCK;
135     if (fcntl(lan_socket_descriptor, F_SETFL, lan_save_file_flags) == -1) {
136 	syslog(LOG_ERR, "%s\n", "trying non-blocking");
137 	return (-3);
138     }
139     return (0);
140 }
141 
lan_recv_close(void)142 int lan_recv_close(void) {
143 
144     if (lan_active == 0)
145 	return (-1);
146 
147     lan_close_rc = close(lan_socket_descriptor);
148     if (lan_close_rc == -1) {
149 	syslog(LOG_ERR, "%s\n", "LAN: close call failed");
150 	return (errno);
151     }
152 
153     return (0);
154 }
155 
lan_recv(void)156 int lan_recv(void) {
157 
158     if (lan_active == 0)
159 	return (-1);
160 
161     lan_recv_message[0] = '\0';
162 
163     lan_recv_rc =
164 	recvfrom(lan_socket_descriptor, lan_recv_message,
165 		 sizeof(lan_recv_message), 0, (struct sockaddr *) &lan_sin,
166 		 &lan_sin_len);
167 
168     if (lan_recv_rc == -1 && errno != EAGAIN) {
169 	recv_error++;
170 	return (errno);
171     } else if (lan_recv_rc == 0 || errno == EAGAIN) {	/* no data */
172 	errno = 0;		/* clear the error */
173     }
174 
175     errno = 0;			/* clear the error */
176 
177     if (lan_recv_message[1] == CLUSTERMSG)
178 	cl_send_inhibit = 1;	// this node does not send cluster info
179 
180     if (lan_recv_rc > 0)
181 	recv_packets++;
182 
183     strcpy(lan_message, lan_recv_message);
184     if (lan_recv_rc > buflen)
185 	buflen = lan_recv_rc;
186 
187     return (0);
188 }
189 
190 // ----------------send routines --------------------------
191 
lan_send_init(void)192 int lan_send_init(void) {
193 
194     if (lan_active == 0)
195 	return (1);
196 
197     for (node = 0; node < nodes; node++) {
198 
199 	bc_hostbyname[node] = gethostbyname(bc_hostaddress[node]);
200 	if (bc_hostbyname[node] == NULL) {
201 	    syslog(LOG_ERR, "%s\n", "LAN: gethostbyname failed");
202 	    return (-1);
203 	}
204 
205 	bzero(&bc_address[node], sizeof(bc_address[node]));	/* empty data structure */
206 	bc_address[node].sin_family = AF_INET;
207 	memcpy(&bc_address[node].sin_addr.s_addr, bc_hostbyname[node]->h_addr,
208 	       sizeof(bc_address[node].sin_addr.s_addr));
209 
210 	bc_address[node].sin_port = htons(resolveService(bc_hostservice[node]));
211 
212 	syslog(LOG_INFO, "open socket: to %d.%d.%d.%d:%d\n",
213 	       (ntohl(bc_address[node].sin_addr.s_addr) & 0xff000000) >> 24,
214 	       (ntohl(bc_address[node].sin_addr.s_addr) & 0x00ff0000) >> 16,
215 	       (ntohl(bc_address[node].sin_addr.s_addr) & 0x0000ff00) >> 8,
216 	       (ntohl(bc_address[node].sin_addr.s_addr) & 0x000000ff) >> 0,
217 	       ntohs(bc_address[node].sin_port));
218 
219 	bc_socket_descriptor[node] = socket(AF_INET, SOCK_DGRAM, 0);
220 
221 	if (bc_socket_descriptor[node] == -1) {
222 	    syslog(LOG_ERR, "%s\n", "LAN: socket call failed");
223 	    return (-1);
224 	}
225     }
226 
227     return (0);
228 }
229 
lan_send_close(void)230 int lan_send_close(void) {
231 
232     if (lan_active == 0)
233 	return (-1);
234 
235     for (node = 0; node < nodes; node++) {
236 
237 	bc_close_rc = close(bc_socket_descriptor[node]);
238 	if (bc_close_rc == -1) {
239 	    syslog(LOG_ERR, "%s\n", "LAN: close call failed");
240 	    return (-1);
241 	}
242     }
243 
244     return (0);
245 }
246 
lan_send(char * lanbuffer)247 int lan_send(char *lanbuffer) {
248 
249     if (lan_active == 0)
250 	return (-1);
251 
252     for (node = 0; node < nodes; node++) {
253 
254 	if (lanbuffer[0] != '\0') {
255 	    bc_sendto_rc = sendto(bc_socket_descriptor[node],
256 				  lanbuffer, 256,
257 				  0, (struct sockaddr *) &bc_address[node],
258 				  sizeof(bc_address[node]));
259 
260 	}
261 
262 	if (bc_sendto_rc == -1) {
263 	    if (send_error[node] >= (send_error_limit[node] + 10)) {
264 		TLF_LOG_INFO("LAN: send problem...!");
265 		send_error_limit[node] += 10;
266 	    } else
267 		send_error[node]++;
268 
269 	} else
270 	    send_packets[node]++;
271     }
272 
273     lanbuffer[0] = '\0';
274 
275     return (0);
276 }
277 
278 /* ----------------- send lan message ----------*/
279 
send_lan_message(int opcode,char * message)280 int send_lan_message(int opcode, char *message) {
281     char sendbuffer[102];
282 
283     sendbuffer[0] = thisnode;
284     sendbuffer[1] = opcode;
285     sendbuffer[2] = '\0';
286     strncat(sendbuffer, message, 98);
287     if (opcode == CLUSTERMSG) {
288 	if (cl_send_inhibit == 0) {
289 	    strcat(sendbuffer, "\n");
290 	    lan_send(sendbuffer);
291 	}
292     }
293 
294     if (opcode == LOGENTRY) {
295 	sendbuffer[82] = '\0';
296 
297 	lan_send(sendbuffer);
298     }
299 
300     if (opcode == TLFSPOT) {
301 	sendbuffer[82] = '\0';
302 	lan_send(sendbuffer);
303     }
304     if (opcode == TLFMSG) {
305 	sendbuffer[82] = '\0';
306 	lan_send(sendbuffer);
307     }
308     if (opcode == FREQMSG) {
309 	sendbuffer[10] = '\0';
310 	lan_send(sendbuffer);
311     }
312     if (opcode == INCQSONUM) {
313 	strcat(sendbuffer, "\n");
314 	lan_send(sendbuffer);
315     }
316     if (opcode == TIMESYNC) {
317 	sendbuffer[14] = '\0';
318 	lan_send(sendbuffer);
319     }
320     if (opcode == QTCRENTRY) {
321 	strcat(sendbuffer, "\n");
322 	sendbuffer[94] = '\0';
323 	lan_send(sendbuffer);
324     }
325     if (opcode == QTCSENTRY) {
326 	strcat(sendbuffer, "\n");
327 	sendbuffer[100] = '\0';
328 	lan_send(sendbuffer);
329     }
330     if (opcode == QTCFLAG) {
331 	strcat(sendbuffer, "\n");
332 	lan_send(sendbuffer);
333     }
334 
335     return (0);
336 }
337 
338 /* ----------------- send talk message ----------*/
talk(void)339 void talk(void) {
340 
341     char talkline[61] = "";
342 
343     mvprintw(LINES - 1, 0, backgrnd_str);
344     mvprintw(LINES - 1, 0, "T>");
345     refreshp();
346     echo();
347     getnstr(talkline, 60);
348     noecho();
349 
350     strcat(talkline, "\n");
351 
352     send_lan_message(TLFMSG, talkline);
353 
354     talkline[0] = '\0';
355     attron(COLOR_PAIR(C_HEADER));
356     mvprintw(LINES - 1, 0, backgrnd_str);
357     refreshp();
358 }
359 
360 /* ----------------- send freq. message ----------*/
361 
send_freq(freq_t freq)362 int send_freq(freq_t freq) {
363 
364     extern int bandinx;
365     extern int trx_control;
366 
367     char fbuffer[8];
368 
369     if (trx_control == 1) {
370 
371 	sprintf(fbuffer, "%7.1f", freq / 1000.0);
372     } else {
373 	switch (bandinx) {
374 
375 	    case 0:
376 		sprintf(fbuffer, " 160.0");
377 		break;
378 
379 	    case 1:
380 		sprintf(fbuffer, "  80.0");
381 		break;
382 
383 	    case 2:
384 		sprintf(fbuffer, "  40.0");
385 		break;
386 
387 	    case 3:
388 		sprintf(fbuffer, "  30.0");
389 		break;
390 
391 	    case 4:
392 		sprintf(fbuffer, "  20.0");
393 		break;
394 
395 	    case 5:
396 		sprintf(fbuffer, "  17.0");
397 		break;
398 
399 	    case 6:
400 		sprintf(fbuffer, "  15.0");
401 		break;
402 
403 	    case 7:
404 		sprintf(fbuffer, "  12.0");
405 		break;
406 
407 	    case 8:
408 		sprintf(fbuffer, "  10.0");
409 		break;
410 
411 	    default:
412 		sprintf(fbuffer, "     ");
413 	}
414     }
415 
416     send_lan_message(FREQMSG, fbuffer);
417 
418     return (0);
419 }
420 
421 /* ----------------- send time message ----------*/
422 
send_time(void)423 int send_time(void) {
424 
425     extern int timeoffset;
426 
427     long now;
428     char timebuffer[14];
429 
430     now = (long)(time(0) + (timeoffset * 3600L));
431 
432     sprintf(timebuffer, "%ld", now);
433     strcat(timebuffer, " ");
434     send_lan_message(TIMESYNC, timebuffer);
435 
436     return (0);
437 }
438