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