1 /*
2  * Tlf - contest logging program for amateur radio operators
3  * Copyright (C) 2001-2002-2003 Rein Couperus <pa0rct@amsat.org>
4  *               2011-2014      Thomas Beierlein <tb@forth-ev.de>
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  *
23  *          clusterinfo +  time update
24  *--------------------------------------------------------------*/
25 
26 
27 #include <pthread.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include <glib.h>
32 
33 #include "bandmap.h"
34 #include "dxcc.h"
35 #include "err_utils.h"
36 #include "get_time.h"
37 #include "getctydata.h"
38 #include "lancode.h"
39 #include "nicebox.h"		// Includes curses.h
40 #include "printcall.h"
41 #include "tlf.h"
42 #include "ui_utils.h"
43 
44 #define MAXMINUTES 30
45 
46 
47 extern int bandinx;
48 extern pthread_mutex_t spot_ptr_mutex;
49 
50 char *bandmap[MAX_SPOTS];
51 int spotarray[MAX_SPOTS];		/* Array of indices into spot_ptr */
52 
53 int loadbandmap(void);
54 int getclusterinfo(void);
55 
clusterinfo(void)56 void clusterinfo(void) {
57 
58     extern int cluster;
59     extern freq_t freq;
60     extern char band[NBANDS][4];
61     extern int bandinx;
62     extern int trx_control;
63     extern char spot_ptr[MAX_SPOTS][82];
64     extern freq_t node_frequencies[MAXNODES];
65     extern char thisnode;
66 
67     int f, j, k;
68     char inputbuffer[160] = "";
69 
70 
71     /* cluster and bandmap display */
72     attron(modify_attr(COLOR_PAIR(NORMCOLOR)));
73 
74     mvprintw(12, 0, "");
75 
76     if (cluster == NOCLUSTER) {
77 	attron(COLOR_PAIR(C_LOG) | A_STANDOUT);
78 
79 	for (int i = 14; i < LINES - 1; i++)
80 	    mvprintw(i, 0, backgrnd_str);
81 	refreshp();
82 
83     }
84 
85     if (cluster == MAP) {
86 
87 	attron(COLOR_PAIR(C_WINDOW) | A_STANDOUT);
88 
89 	loadbandmap();
90 
91     }
92 
93     if (cluster == FREQWINDOW) {
94 	for (f = 0; f < 8; f++)
95 	    mvprintw(15 + f, 4, "                           ");
96 
97 	if (trx_control == 0)
98 	    node_frequencies[thisnode - 'A'] = atof(band[bandinx]);
99 	else
100 	    node_frequencies[thisnode - 'A'] = freq;
101 
102 	for (f = 0; f < MAXNODES; f++) {
103 	    if (node_frequencies[f] != 0)
104 		mvprintw(15 + f, 4, " Stn %c : %5.0f", 'A' + f,
105 			 node_frequencies[f] / 1000.0);
106 	}
107 	nicebox(14, 3, 8, 27, "Frequencies");
108     }
109 
110     if (cluster == CLUSTER) {
111 
112 	attron(COLOR_PAIR(C_WINDOW) | A_STANDOUT);
113 
114 	g_strlcpy(inputbuffer, backgrnd_str, 79);
115 
116 	for (j = 15; j <= LINES - 3; j++) {
117 	    mvprintw(j, 1, "%s", inputbuffer);
118 	}
119 
120 
121 	/** \todo minimize lock time */
122 	pthread_mutex_lock(&spot_ptr_mutex);
123 
124 	k = getclusterinfo();
125 
126 	if (k > (MAX_SPOTS - 1)) {
127 	    k = MAX_SPOTS - 1;
128 	}
129 
130 	k -= (LINES - 3 - 14) + 1;
131 	if (k < 0)
132 	    k = -1;
133 
134 
135 	for (j = 15; j <= LINES - 3; j++) {
136 	    k++;
137 	    if (k < (MAX_SPOTS - 1) && spotarray[k] > -1) {
138 		if (k > MAX_SPOTS - 1)
139 		    k = MAX_SPOTS - 1;
140 
141 		inputbuffer[0] = '\0';
142 
143 		if (spotarray[k] >= 0 && spotarray[k] < MAX_SPOTS)
144 		    g_strlcpy(inputbuffer, spot_ptr[spotarray[k]], 79);
145 		else {
146 		    TLF_LOG_INFO("error in packet table");
147 		}
148 
149 		if (strlen(inputbuffer) > 14) {
150 		    mvprintw(j, 1, "%s", inputbuffer);
151 		}
152 	    }
153 	}
154 
155 	pthread_mutex_unlock(&spot_ptr_mutex);
156 
157 	nicebox(14, 0, LINES - 3 - 14, 78, "Cluster");
158 	refreshp();
159     }
160     printcall();
161 }
162 
163 
164 
165 /* ----------------------------------------------------*/
166 
loadbandmap(void)167 int loadbandmap(void) {
168 
169     extern char *bandmap[MAX_SPOTS];
170     extern struct tm *time_ptr;
171     extern int xplanet;
172     extern char markerfile[];
173     extern char lastmsg[];
174     extern char spot_ptr[MAX_SPOTS][82];
175     extern int nr_of_spots;
176 
177 
178     int i = 0, j, m, x;
179     unsigned int k;
180     int spotminutes = 0;
181     int sysminutes = 0;
182     int timediff = 0;
183     int linepos;
184     int spot_age[MAX_SPOTS];
185     freq_t spot_freq[MAX_SPOTS];
186 
187     char thisline[83];
188     char spotcall[20];
189     char spottime[6];
190     char spotline[38];
191     char callcopy[20];
192     FILE *fp;
193     char marker_out[60];
194     char color[sizeof("Magenta")];
195     int lon;
196     int lat;
197     int zz;
198     int nofile = 0;
199     int iswarc = 0;
200     char xplanetmsg[160];
201     dxcc_data *dx;
202 
203 
204     for (i = 0; i < MAX_SPOTS; i++) {
205 	if (bandmap[i] != NULL) {
206 	    g_free(bandmap[i]);
207 	    bandmap[i] = NULL;
208 	}
209 
210 	spot_age[i] = 0;
211 	spot_freq[i] = 0.;
212     }
213 
214     i = 0;
215 
216     get_time();
217     sysminutes = 60 * time_ptr->tm_hour + time_ptr->tm_min;
218 
219     /* parse log of cluster output and find DX announcements.
220      * Copy them to bandmap array and find spot_age and spot_freq
221      */
222 
223     pthread_mutex_lock(&spot_ptr_mutex);
224 
225     for (j = 0; j < nr_of_spots; j++) {
226 
227 	g_strlcpy(thisline, spot_ptr[j], sizeof(thisline));
228 	if (strncmp(thisline, "DX de ", 6) == 0) {
229 
230 	    g_strlcpy(spotcall, thisline + 26, 6);
231 
232 	    strncpy(spottime, thisline + 70, 4);	// how old?
233 	    spottime[4] = spottime[3];
234 	    spottime[3] = spottime[2];
235 	    spottime[2] = ':';
236 	    spottime[5] = '\0';
237 	    spotminutes = 60 * atoi(spottime) + atoi(spottime + 3);
238 	    timediff = (sysminutes - spotminutes) + 5;
239 	    if (timediff + 30 < 0)
240 		timediff += 1440;
241 
242 	    /* is spot recent? */
243 	    if ((timediff + 30) <= (MAXMINUTES + 30)) {
244 
245 		/* look for duplicates already in bandmap
246 		 * => kill older one and keep younger entry */
247 		for (k = 0; k < i; k++) {
248 		    g_strlcpy(callcopy, bandmap[k] + 26, 6);
249 
250 		    if (strncmp(callcopy, spotcall, 4) == 0) {
251 			bandmap[k][0] = 'd';
252 			break;
253 		    }
254 		}
255 
256 		bandmap[i] = g_strdup(thisline);
257 		spot_age[i] = timediff;
258 		spot_freq[i] = atof(thisline + 17);
259 		i++;
260 	    }
261 	}
262     }
263 
264 
265     pthread_mutex_unlock(&spot_ptr_mutex);
266 
267     linepos = (i < 8 ? 0 : i - 8);
268 
269     /* prune markerfile by opening it for write */
270     if (xplanet > 0 && nofile == 0) {
271 	if ((fp = fopen(markerfile, "w")) == NULL) {
272 	    nofile = 1;			/* remember: no write possible */
273 	    TLF_LOG_INFO("Opening marker file not possible.");
274 	} else
275 	    fclose(fp);
276     }
277 
278     for (j = linepos; j < linepos + 8; j++) {
279 
280 	if (bandmap[j] != NULL) {
281 	    g_strlcpy(spotline, bandmap[j] + 17, 23);	// freq and call
282 	    g_strlcpy(spottime, bandmap[j] + 70, 6);	// time
283 	    strcat(spotline, spottime);
284 
285 	    strncpy(callcopy, bandmap[j] + 26, 16);	// call
286 	    for (m = 0; m < 16; m++) {
287 		if (callcopy[m] == ' ') {
288 		    callcopy[m] = '\0';
289 		    break;
290 		}	/* use strcspn? */
291 	    }
292 
293 	    x = getctynr(callcopy);		// CTY of station
294 
295 
296 	    if (x != 0 && xplanet > 0 && nofile == 0) {
297 
298 		if ((fp = fopen(markerfile, "a")) == NULL) {
299 		    TLF_LOG_INFO("Opening markerfile not possible.");
300 		} else {
301 
302 		    /* show no callsign if MARKERDOTS */
303 		    if (xplanet == 2)
304 			callcopy[0] = '\0';
305 
306 		    dx = dxcc_by_index(x);
307 		    lon = (int)(dx -> lon) * -1;
308 		    lat = (int)(dx -> lat);
309 
310 		    *color = '\0';
311 
312 		    if (spot_age[j] > 15)
313 			strcat(color, "Green");
314 		    else {
315 			iswarc = 0;
316 			if (spot_freq[j] >= 10100.0 && spot_freq[j] <= 10150.0)
317 			    iswarc = 1;
318 			if (spot_freq[j] >= 18068.0 && spot_freq[j] <= 18168.0)
319 			    iswarc = 1;
320 			if (spot_freq[j] >= 24890.0 && spot_freq[j] <= 24990.0)
321 			    iswarc = 1;
322 
323 			if (iswarc == 0) {
324 			    if (spot_freq[j] < 3500.0)
325 				strcat(color, "Red");
326 			    if (spot_freq[j] >= 3500.0
327 				    && spot_freq[j] <= 4000.0)
328 				strcat(color, "Magenta");
329 			    if (spot_freq[j] >= 7000.0
330 				    && spot_freq[j] <= 7300.0)
331 				strcat(color, "Yellow");
332 			    if (spot_freq[j] >= 14000.0
333 				    && spot_freq[j] <= 14350.0)
334 				strcat(color, "Blue");
335 			    if (spot_freq[j] >= 21000.0
336 				    && spot_freq[j] <= 21450.0)
337 				strcat(color, "White");
338 			    if (spot_freq[j] >= 28000.0
339 				    && spot_freq[j] <= 29700.0)
340 				strcat(color, "Green");
341 
342 			} else {
343 			    strcat(color, "Cyan");
344 			}
345 		    }
346 
347 		    if (*color != '\0') {
348 			sprintf(marker_out, "%4d   %4d   \"%s\"   color=%s\n",
349 				lat, lon, callcopy, color);
350 
351 			fputs(marker_out, fp);
352 		    }
353 
354 
355 		    fclose(fp);
356 		}
357 	    }
358 
359 	}
360     }
361 
362     /* append last dx cluster message to markerfile; will be shown at bottom */
363     if (xplanet == 1 && nofile == 0) {
364 
365 	strcpy(xplanetmsg, " -82 -120 ");
366 	strcat(xplanetmsg, "\"");
367 	strcat(xplanetmsg, lastmsg);
368 
369 	for (zz = 0; zz < strlen(lastmsg); zz++)
370 	    if (lastmsg[zz] == 34)
371 		lastmsg[zz] = ' ';
372 
373 	strcat(xplanetmsg, "\"   color=Cyan\n");
374 
375 	if ((fp = fopen(markerfile, "a")) == NULL) {
376 	    TLF_LOG_INFO("Opening markerfile not possible.");
377 	} else {
378 	    if (strlen(xplanetmsg) > 20)
379 		fputs(xplanetmsg, fp);
380 
381 	    fclose(fp);
382 	}
383     }
384 
385 
386     bandmap_show();
387 
388     refreshp();
389 
390     return (i);			/* nr of found spot lines */
391 }
392 
393 
394 
getclusterinfo(void)395 int getclusterinfo(void) {
396 
397     extern char spot_ptr[MAX_SPOTS][82];
398     extern int nr_of_spots;
399     extern int announcefilter;
400     extern char call[];
401 
402     int i;
403     int si;
404     char calldupe[12];
405 
406     strcpy(calldupe, call);
407     calldupe[strlen(call) - 1] = '\0';
408 
409     for (si = 0; si < (MAX_SPOTS - 2); si++)
410 	spotarray[si] = -1;
411 
412     i = 0;
413     si = 0;
414 
415     while (1) {
416 
417 	if (strstr(spot_ptr[i], "DX de") != NULL) {
418 	    spotarray[si] = i;
419 	    si++;
420 
421 	} else if (strstr(spot_ptr[i], calldupe) != NULL) {
422 	    if ((announcefilter <= 2)) {
423 		spotarray[si] = i;
424 		si++;
425 	    }
426 
427 	} else if (strstr(spot_ptr[i], "To ALL") != NULL) {
428 	    if ((announcefilter <= 1)) {
429 		spotarray[si] = i;
430 		si++;
431 	    }
432 
433 	} else if ((announcefilter == 0)
434 		   && (strlen(spot_ptr[i]) > 20)) {
435 	    spotarray[si] = i;
436 	    si++;
437 	}
438 
439 	i++;
440 
441 	if (i > (nr_of_spots - 1))
442 	    break;
443     }
444 
445     return si;
446 }
447 
448 
449