altoslib: Clean up random rebase failures
[fw/altos] / altosui / Altos.java
1 /*
2  * Copyright © 2010 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package altosui;
19
20 import java.awt.*;
21 import java.util.*;
22 import java.text.*;
23 import java.nio.charset.Charset;
24
25 import libaltosJNI.*;
26
27 import org.altusmetrum.AltosLib.*;
28
29 public class Altos extends AltosLib {
30
31         static final int tab_elt_pad = 5;
32
33         static Font label_font;
34         static Font value_font;
35         static Font status_font;
36         static Font table_label_font;
37         static Font table_value_font;
38
39         final static int font_size_small = 1;
40         final static int font_size_medium = 2;
41         final static int font_size_large = 3;
42
43         static void set_fonts(int size) {
44                 int     brief_size;
45                 int     table_size;
46                 int     status_size;
47
48                 switch (size) {
49                 case font_size_small:
50                         brief_size = 16;
51                         status_size = 18;
52                         table_size = 11;
53                         break;
54                 default:
55                 case font_size_medium:
56                         brief_size = 22;
57                         status_size = 24;
58                         table_size = 14;
59                         break;
60                 case font_size_large:
61                         brief_size = 26;
62                         status_size = 30;
63                         table_size = 17;
64                         break;
65                 }
66                 label_font = new Font("Dialog", Font.PLAIN, brief_size);
67                 value_font = new Font("Monospaced", Font.PLAIN, brief_size);
68                 status_font = new Font("SansSerif", Font.BOLD, status_size);
69                 table_label_font = new Font("SansSerif", Font.PLAIN, table_size);
70                 table_value_font = new Font("Monospaced", Font.PLAIN, table_size);
71         }
72
73         static final int text_width = 20;
74
75         static void initialize_map()
76         {
77                 string_to_state.put("startup", ao_flight_startup);
78                 string_to_state.put("idle", ao_flight_idle);
79                 string_to_state.put("pad", ao_flight_pad);
80                 string_to_state.put("boost", ao_flight_boost);
81                 string_to_state.put("fast", ao_flight_fast);
82                 string_to_state.put("coast", ao_flight_coast);
83                 string_to_state.put("drogue", ao_flight_drogue);
84                 string_to_state.put("apogee", ao_flight_coast);
85                 string_to_state.put("main", ao_flight_main);
86                 string_to_state.put("landed", ao_flight_landed);
87                 string_to_state.put("invalid", ao_flight_invalid);
88                 map_initialized = true;
89         }
90
91         static int telemetry_len(int telemetry) {
92                 if (telemetry <= ao_telemetry_max)
93                         return ao_telemetry_len[telemetry];
94                 throw new IllegalArgumentException(String.format("Invalid telemetry %d",
95                                                                  telemetry));
96         }
97
98         static String telemetry_name(int telemetry) {
99                 if (telemetry <= ao_telemetry_max)
100                         return ao_telemetry_name[telemetry];
101                 throw new IllegalArgumentException(String.format("Invalid telemetry %d",
102                                                                  telemetry));
103         }
104         
105         static String[] state_to_string = {
106                 "startup",
107                 "idle",
108                 "pad",
109                 "boost",
110                 "fast",
111                 "coast",
112                 "drogue",
113                 "main",
114                 "landed",
115                 "invalid",
116         };
117
118         static String[] state_to_string_capital = {
119                 "Startup",
120                 "Idle",
121                 "Pad",
122                 "Boost",
123                 "Fast",
124                 "Coast",
125                 "Drogue",
126                 "Main",
127                 "Landed",
128                 "Invalid",
129         };
130
131         static public int state(String state) {
132                 if (!map_initialized)
133                         initialize_map();
134                 if (string_to_state.containsKey(state))
135                         return string_to_state.get(state);
136                 return ao_flight_invalid;
137         }
138
139         static public String state_name(int state) {
140                 if (state < 0 || state_to_string.length <= state)
141                         return "invalid";
142                 return state_to_string[state];
143         }
144
145         static final int AO_GPS_VALID = (1 << 4);
146         static final int AO_GPS_RUNNING = (1 << 5);
147         static final int AO_GPS_DATE_VALID = (1 << 6);
148         static final int AO_GPS_NUM_SAT_SHIFT = 0;
149         static final int AO_GPS_NUM_SAT_MASK = 0xf;
150
151         static final int AO_LOG_FORMAT_UNKNOWN = 0;
152         static final int AO_LOG_FORMAT_FULL = 1;
153         static final int AO_LOG_FORMAT_TINY = 2;
154         static final int AO_LOG_FORMAT_TELEMETRY = 3;
155         static final int AO_LOG_FORMAT_TELESCIENCE = 4;
156         static final int AO_LOG_FORMAT_MEGAMETRUM = 5;
157         static final int AO_LOG_FORMAT_NONE = 127;
158
159         static boolean isspace(int c) {
160                 switch (c) {
161                 case ' ':
162                 case '\t':
163                         return true;
164                 }
165                 return false;
166         }
167
168         static boolean ishex(int c) {
169                 if ('0' <= c && c <= '9')
170                         return true;
171                 if ('a' <= c && c <= 'f')
172                         return true;
173                 if ('A' <= c && c <= 'F')
174                         return true;
175                 return false;
176         }
177
178         static boolean ishex(String s) {
179                 for (int i = 0; i < s.length(); i++)
180                         if (!ishex(s.charAt(i)))
181                                 return false;
182                 return true;
183         }
184
185         static int fromhex(int c) {
186                 if ('0' <= c && c <= '9')
187                         return c - '0';
188                 if ('a' <= c && c <= 'f')
189                         return c - 'a' + 10;
190                 if ('A' <= c && c <= 'F')
191                         return c - 'A' + 10;
192                 return -1;
193         }
194
195         static int fromhex(String s) throws NumberFormatException {
196                 int c, v = 0;
197                 for (int i = 0; i < s.length(); i++) {
198                         c = s.charAt(i);
199                         if (!ishex(c)) {
200                                 if (i == 0)
201                                         throw new NumberFormatException(String.format("invalid hex \"%s\"", s));
202                                 return v;
203                         }
204                         v = v * 16 + fromhex(c);
205                 }
206                 return v;
207         }
208
209         static boolean isdec(int c) {
210                 if ('0' <= c && c <= '9')
211                         return true;
212                 return false;
213         }
214
215         static boolean isdec(String s) {
216                 for (int i = 0; i < s.length(); i++)
217                         if (!isdec(s.charAt(i)))
218                                 return false;
219                 return true;
220         }
221
222         static int fromdec(int c) {
223                 if ('0' <= c && c <= '9')
224                         return c - '0';
225                 return -1;
226         }
227
228         static int int8(int[] bytes, int i) {
229                 return (int) (byte) bytes[i];
230         }
231
232         static int uint8(int[] bytes, int i) {
233                 return bytes[i];
234         }
235
236         static int int16(int[] bytes, int i) {
237                 return (int) (short) (bytes[i] + (bytes[i+1] << 8));
238         }
239
240         static int uint16(int[] bytes, int i) {
241                 return bytes[i] + (bytes[i+1] << 8);
242         }
243
244         static int uint32(int[] bytes, int i) {
245                 return bytes[i] +
246                         (bytes[i+1] << 8) +
247                         (bytes[i+2] << 16) +
248                         (bytes[i+3] << 24);
249         }
250
251         static final Charset    unicode_set = Charset.forName("UTF-8");
252
253         static String string(int[] bytes, int s, int l) {
254                 if (s + l > bytes.length) {
255                         if (s > bytes.length) {
256                                 s = bytes.length;
257                                 l = 0;
258                         } else {
259                                 l = bytes.length - s;
260                         }
261                 }
262
263                 int i;
264                 for (i = l - 1; i >= 0; i--)
265                         if (bytes[s+i] != 0)
266                                 break;
267
268                 l = i + 1;
269                 byte[]  b = new byte[l];
270
271                 for (i = 0; i < l; i++)
272                         b[i] = (byte) bytes[s+i];
273                 String n = new String(b, unicode_set);
274                 return n;
275         }
276
277         static int hexbyte(String s, int i) {
278                 int c0, c1;
279
280                 if (s.length() < i + 2)
281                         throw new NumberFormatException(String.format("invalid hex \"%s\"", s));
282                 c0 = s.charAt(i);
283                 if (!Altos.ishex(c0))
284                         throw new NumberFormatException(String.format("invalid hex \"%c\"", c0));
285                 c1 = s.charAt(i+1);
286                 if (!Altos.ishex(c1))
287                         throw new NumberFormatException(String.format("invalid hex \"%c\"", c1));
288                 return Altos.fromhex(c0) * 16 + Altos.fromhex(c1);
289         }
290
291         static int[] hexbytes(String s) {
292                 int     n;
293                 int[]   r;
294                 int     i;
295
296                 if ((s.length() & 1) != 0)
297                         throw new NumberFormatException(String.format("invalid line \"%s\"", s));
298                 n = s.length() / 2;
299                 r = new int[n];
300                 for (i = 0; i < n; i++)
301                         r[i] = Altos.hexbyte(s, i * 2);
302                 return r;
303         }
304
305         static int fromdec(String s) throws NumberFormatException {
306                 int c, v = 0;
307                 int sign = 1;
308                 for (int i = 0; i < s.length(); i++) {
309                         c = s.charAt(i);
310                         if (i == 0 && c == '-') {
311                                 sign = -1;
312                         } else if (!isdec(c)) {
313                                 if (i == 0)
314                                         throw new NumberFormatException(String.format("invalid number \"%s\"", s));
315                                 return v;
316                         } else
317                                 v = v * 10 + fromdec(c);
318                 }
319                 return v * sign;
320         }
321
322         static String replace_extension(String input, String extension) {
323                 int dot = input.lastIndexOf(".");
324                 if (dot > 0)
325                         input = input.substring(0,dot);
326                 return input.concat(extension);
327         }
328
329         static public boolean initialized = false;
330         static public boolean loaded_library = false;
331
332         public static boolean load_library() {
333                 if (!initialized) {
334                         try {
335                                 System.loadLibrary("altos");
336                                 libaltos.altos_init();
337                                 loaded_library = true;
338                         } catch (UnsatisfiedLinkError e) {
339                                 try {
340                                         System.loadLibrary("altos64");
341                                         libaltos.altos_init();
342                                         loaded_library = true;
343                                 } catch (UnsatisfiedLinkError e2) {
344                                         loaded_library = false;
345                                 }
346                         }
347                         initialized = true;
348                 }
349                 return loaded_library;
350         }
351
352         static int usb_vendor_altusmetrum() {
353                 load_library();
354                 return 0xfffe;
355         }
356
357         static int usb_product_altusmetrum() {
358                 load_library();
359                 return 0x000a;
360         }
361
362         static int usb_product_altusmetrum_min() {
363                 load_library();
364                 return 0x000a;
365         }
366
367         static int usb_product_altusmetrum_max() {
368                 load_library();
369                 return 0x0013;
370         }
371
372         static int usb_product_telemetrum() {
373                 load_library();
374                 return 0x000b;
375         }
376
377         static int usb_product_teledongle() {
378                 load_library();
379                 return 0x000c;
380         }
381
382         static int usb_product_teleterra() {
383                 load_library();
384                 return 0x000d;
385         }
386
387         static int usb_product_telebt() {
388                 load_library();
389                 return 0x000e;
390         }
391
392         static int usb_product_telelaunch() {
393                 load_library();
394                 return 0x000f;
395         }
396
397         static int usb_product_telelco() {
398                 load_library();
399                 return 0x0010;
400         }
401
402         static int usb_product_telescience() {
403                 load_library();
404                 return 0x0011;
405         }
406
407         static int usb_product_telepyro() {
408                 load_library();
409                 return 0x0012;
410         }
411
412         public final static int vendor_altusmetrum = usb_vendor_altusmetrum();
413         public final static int product_altusmetrum = usb_product_altusmetrum();
414         public final static int product_telemetrum = usb_product_telemetrum();
415         public final static int product_teledongle = usb_product_teledongle();
416         public final static int product_teleterra = usb_product_teleterra();
417         public final static int product_telebt = usb_product_telebt();
418         public final static int product_telelaunch = usb_product_telelaunch();
419         public final static int product_tele10 = usb_product_telelco();
420         public final static int product_telescience = usb_product_telescience();
421         public final static int product_telepyro = usb_product_telepyro();
422         public final static int product_altusmetrum_min = usb_product_altusmetrum_min();
423         public final static int product_altusmetrum_max = usb_product_altusmetrum_max();
424
425         public final static int product_any = 0x10000;
426         public final static int product_basestation = 0x10000 + 1;
427
428         static String bt_product_telebt() {
429                 load_library();
430                 return "TeleBT";
431         }
432
433         public final static String bt_product_telebt = bt_product_telebt();
434
435         public static AltosBTKnown bt_known = new AltosBTKnown();
436 }