1 /*
2     Gpredict: Real-time satellite tracking and orbit prediction program
3 
4     Copyright (C)  2001-2016  Alexandru Csete.
5 
6     Authors: Alexandru Csete <oz9aec@gmail.com>
7 
8     Comments, questions and bugreports should be submitted via
9     http://sourceforge.net/projects/gpredict/
10     More details can be found at the project home page:
11 
12             http://gpredict.oz9aec.net/
13 
14     This program is free software; you can redistribute it and/or modify
15     it under the terms of the GNU General Public License as published by
16     the Free Software Foundation; either version 2 of the License, or
17     (at your option) any later version.
18 
19     This program is distributed in the hope that it will be useful,
20     but WITHOUT ANY WARRANTY; without even the implied warranty of
21     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22     GNU General Public License for more details.
23 
24     You should have received a copy of the GNU General Public License
25     along with this program; if not, visit http://www.fsf.org/
26 
27 */
28 #include <glib/gi18n.h>
29 #include <gtk/gtk.h>
30 
31 #include "compat.h"
32 #include "gpredict-utils.h"
33 #include "sat-log.h"
34 #include "trsp-conf.h"
35 
36 #define KEY_UP_LOW      "UP_LOW"
37 #define KEY_UP_HIGH     "UP_HIGH"
38 #define KEY_DOWN_LOW    "DOWN_LOW"
39 #define KEY_DOWN_HIGH   "DOWN_HIGH"
40 #define KEY_INVERT      "INVERT"
41 #define KEY_MODE        "MODE"
42 #define KEY_BAUD        "BAUD"
43 
check_trsp_freq(trsp_t * trsp)44 static void check_trsp_freq(trsp_t * trsp)
45 {
46     /* ensure we don't have any negative frequencies */
47     if (trsp->downlow < 0)
48         trsp->downlow = 0;
49     if (trsp->downhigh < 0)
50         trsp->downhigh = 0;
51     if (trsp->uplow < 0)
52         trsp->uplow = 0;
53     if (trsp->uphigh < 0)
54         trsp->uphigh = 0;
55 
56     if (trsp->downlow == 0 && trsp->downhigh > 0)
57         trsp->downlow = trsp->downhigh;
58     else if (trsp->downhigh == 0 && trsp->downlow > 0)
59         trsp->downhigh = trsp->downlow;
60 
61     if (trsp->uplow == 0 && trsp->uphigh > 0)
62         trsp->uplow = trsp->uphigh;
63     else if (trsp->uphigh == 0 && trsp->uplow > 0)
64         trsp->uphigh = trsp->uplow;
65 }
66 
67 /**
68  * Read transponder data file.
69  *
70  * @param catnum The catalog number of the satellite to read transponders for.
71  * @return  The new transponder list.
72  */
read_transponders(guint catnum)73 GSList *read_transponders(guint catnum)
74 {
75     GSList         *trsplist = NULL;
76     trsp_t         *trsp;
77     GKeyFile       *cfg = NULL;
78     GError         *error = NULL;
79     gchar          *name, *fname;
80     gchar         **groups;
81     gsize           numgrp, i;
82 
83 #define INFO_MSG N_("%s: Could not read %s from %s:'%s'. Using default.")
84 
85     name = g_strdup_printf("%d.trsp", catnum);
86     fname = trsp_file_name(name);
87 
88     cfg = g_key_file_new();
89     if (!g_key_file_load_from_file
90         (cfg, fname, G_KEY_FILE_KEEP_COMMENTS, &error))
91     {
92         sat_log_log(SAT_LOG_LEVEL_ERROR,
93                     _("%s: Error reading %s: %s"),
94                     __FILE__, fname, error->message);
95         g_clear_error(&error);
96 
97         g_key_file_free(cfg);
98 
99         return NULL;
100     }
101 
102     /* get list of transponders */
103     groups = g_key_file_get_groups(cfg, &numgrp);
104 
105     /* load each transponder */
106     if (numgrp == 0)
107     {
108         sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: %s contains 0 transponders"),
109                     __func__, fname);
110 
111         goto done;
112     }
113 
114     for (i = 0; i < numgrp; i++)
115     {
116         trsp = g_try_new(trsp_t, 1);
117         if (G_UNLIKELY(trsp == NULL))
118         {
119             sat_log_log(SAT_LOG_LEVEL_ERROR,
120                         _("%s: Failed to allocate memory for trsp data"),
121                         __func__);
122             goto done;
123         }
124 
125         /* read transponder data */
126         trsp->name = g_strdup(groups[i]);
127 
128         trsp->uplow = g_key_file_get_int64(cfg, groups[i], KEY_UP_LOW, &error);
129         if (error != NULL)
130         {
131             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_UP_LOW,
132                         name, groups[i]);
133             g_clear_error(&error);
134         }
135 
136         trsp->uphigh = g_key_file_get_int64(cfg, groups[i], KEY_UP_HIGH,
137                                             &error);
138         if (error != NULL)
139         {
140             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_UP_HIGH,
141                         name, groups[i]);
142             g_clear_error(&error);
143         }
144 
145         trsp->downlow = g_key_file_get_int64(cfg, groups[i], KEY_DOWN_LOW,
146                                              &error);
147         if (error != NULL)
148         {
149             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_DOWN_LOW,
150                         name, groups[i]);
151             g_clear_error(&error);
152         }
153 
154         trsp->downhigh = g_key_file_get_int64(cfg, groups[i], KEY_DOWN_HIGH,
155                                               &error);
156         if (error != NULL)
157         {
158             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_DOWN_HIGH,
159                         name, groups[i]);
160             g_clear_error(&error);
161         }
162 
163         /* check data to ensure consistency */
164         check_trsp_freq(trsp);
165 
166         trsp->invert = g_key_file_get_boolean(cfg, groups[i],
167                                               KEY_INVERT, &error);
168         if (error != NULL)
169         {
170             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_INVERT,
171                         name, groups[i]);
172             g_clear_error(&error);
173             trsp->invert = FALSE;
174         }
175 
176         trsp->mode = g_key_file_get_string(cfg, groups[i], KEY_MODE, &error);
177         if (error != NULL)
178         {
179             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_MODE,
180                         name, groups[i]);
181             g_clear_error(&error);
182         }
183 
184         trsp->baud = g_key_file_get_double(cfg, groups[i], KEY_BAUD, &error);
185         if (error != NULL)
186         {
187             sat_log_log(SAT_LOG_LEVEL_INFO, INFO_MSG, __func__, KEY_BAUD,
188                         name, groups[i]);
189             g_clear_error(&error);
190         }
191 
192         /* add transponder to list */
193         trsplist = g_slist_append(trsplist, trsp);
194     }
195 
196   done:
197     g_strfreev(groups);
198     g_key_file_free(cfg);
199     g_free(name);
200     g_free(fname);
201 
202     return trsplist;
203 }
204 
205 /**
206  * Write transponder list to file.
207  *
208  * @param catnum The catalog number of the satellite.
209  * @param trsplist Pointer to a GSList of trsp_t structures.
210  *
211  * The transponder list is written to a file called "catnum.trsp". If the file
212  * already exists, its contents will be deleted.
213  */
write_transponders(guint catnum,GSList * trsp_list)214 void write_transponders(guint catnum, GSList * trsp_list)
215 {
216     trsp_t         *trsp;
217     GKeyFile       *trsp_data = NULL;
218     gchar          *file_name;
219     gchar          *trsp_file;
220     gint            i, n, trsp_written;
221 
222     file_name = g_strdup_printf("%d.trsp", catnum);
223     trsp_file = trsp_file_name(file_name);
224     trsp_data = g_key_file_new();
225     trsp_written = 0;
226 
227     n = g_slist_length(trsp_list);
228     for (i = 0; i < n; i++)
229     {
230         trsp = (trsp_t *) g_slist_nth_data(trsp_list, i);
231         if (!trsp->name)
232         {
233             sat_log_log(SAT_LOG_LEVEL_ERROR,
234                         _("%s: Skipping transponder at index %d (no name)"),
235                         __func__, i);
236             continue;
237         }
238 
239         if (trsp->uplow > 0)
240             g_key_file_set_int64(trsp_data, trsp->name, KEY_UP_LOW,
241                                  trsp->uplow);
242         if (trsp->uphigh > 0)
243             g_key_file_set_int64(trsp_data, trsp->name, KEY_UP_HIGH,
244                                  trsp->uphigh);
245         if (trsp->downlow > 0)
246             g_key_file_set_int64(trsp_data, trsp->name, KEY_DOWN_LOW,
247                                  trsp->downlow);
248         if (trsp->downhigh > 0)
249             g_key_file_set_int64(trsp_data, trsp->name, KEY_DOWN_HIGH,
250                                  trsp->downhigh);
251         if (trsp->baud > 0.0)
252             g_key_file_set_double(trsp_data, trsp->name, KEY_BAUD, trsp->baud);
253         if (trsp->invert)
254             g_key_file_set_boolean(trsp_data, trsp->name, KEY_INVERT, TRUE);
255         if (trsp->mode)
256             g_key_file_set_string(trsp_data, trsp->name, KEY_MODE, trsp->name);
257     }
258 
259     if (gpredict_save_key_file(trsp_data, trsp_file))
260     {
261         sat_log_log(SAT_LOG_LEVEL_ERROR,
262                     _("%s: Error writing transponder data to %s"),
263                     __func__, file_name);
264     }
265     else
266     {
267         sat_log_log(SAT_LOG_LEVEL_INFO,
268                     _("Wrote %d transmponders to %s"),
269                     trsp_written, trsp_file_name);
270     }
271 
272     g_key_file_free(trsp_data);
273     g_free(file_name);
274     g_free(trsp_file);
275 }
276 
277 /**
278  * Free transponder list.
279  *
280  * @param trsplist Pointer to a GSList of trsp_t structures.
281  */
free_transponders(GSList * trsplist)282 void free_transponders(GSList * trsplist)
283 {
284     gint            i, n;
285     trsp_t         *trsp;
286 
287     n = g_slist_length(trsplist);
288     for (i = 0; i < n; i++)
289     {
290         trsp = (trsp_t *) g_slist_nth_data(trsplist, i);
291         g_free(trsp->name);
292         if (trsp->mode)
293             g_free(trsp->mode);
294         g_free(trsp);
295     }
296     g_slist_free(trsplist);
297     trsplist = NULL;
298 }
299