fde8c101a5df382968d93099a97d60f91090ceed
[fw/altos] / altoslib / AltosIdleMonitor.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 org.altusmetrum.altoslib_11;
19
20 import java.io.*;
21 import java.util.concurrent.*;
22
23
24 public class AltosIdleMonitor extends Thread {
25         AltosLink               link;
26         AltosIdleMonitorListener        listener;
27
28         AltosIdleFetch          fetch;
29
30         boolean                 remote;
31         boolean                 close_on_exit;
32         double                  frequency;
33         String                  callsign;
34
35         AltosListenerState      listener_state;
36         AltosConfigData         config_data;
37         AltosGPS                gps;
38
39         void start_link() throws InterruptedException, TimeoutException {
40                 if (remote) {
41                         link.set_radio_frequency(frequency);
42                         link.set_callsign(callsign);
43                         link.start_remote();
44                 } else
45                         link.flush_input();
46         }
47
48         boolean stop_link() throws InterruptedException, TimeoutException {
49                 if (remote)
50                         link.stop_remote();
51                 return link.reply_abort;
52         }
53
54         boolean update_state(AltosState state) throws InterruptedException, TimeoutException, AltosUnknownProduct {
55                 boolean         worked = false;
56                 boolean         aborted = false;
57
58                 try {
59                         start_link();
60                         fetch.update_state(state);
61                         if (!link.has_error && !link.reply_abort)
62                                 worked = true;
63                 } finally {
64                         aborted = stop_link();
65                         if (worked) {
66                                 if (remote)
67                                         state.set_rssi(link.rssi(), 0);
68                                 listener_state.battery = link.monitor_battery();
69                         }
70                 }
71                 return aborted;
72         }
73
74         public void set_frequency(double in_frequency) {
75                 frequency = in_frequency;
76                 link.abort_reply();
77         }
78
79         public void set_callsign(String in_callsign) {
80                 callsign = in_callsign;
81                 link.abort_reply();
82         }
83
84         public void abort() throws InterruptedException {
85                 while (isAlive()) {
86                         interrupt();
87                         link.abort_reply();
88                         Thread.sleep(100);
89                 }
90                 join();
91         }
92
93         public void run() {
94                 AltosState state = new AltosState();
95                 try {
96                         for (;;) {
97                                 try {
98                                         link.config_data();
99                                         update_state(state);
100                                         listener.update(state, listener_state);
101                                 } catch (TimeoutException te) {
102                                 } catch (AltosUnknownProduct ae) {
103                                         listener.error(String.format("Unknown product \"%s\"", ae.product));
104                                 }
105                                 if (link.has_error || link.reply_abort) {
106                                         listener.failed();
107                                         break;
108                                 }
109                                 Thread.sleep(1000);
110                         }
111                 } catch (InterruptedException ie) {
112                 }
113                 if (close_on_exit) {
114                         try {
115                                 link.close();
116                         } catch (InterruptedException ie) {
117                         }
118                 }
119         }
120
121         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote, boolean in_close_on_exit) {
122                 listener = in_listener;
123                 link = in_link;
124                 remote = in_remote;
125                 close_on_exit = in_close_on_exit;
126                 listener_state = new AltosListenerState();
127                 fetch = new AltosIdleFetch(link);
128         }
129
130         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote) {
131                 this(in_listener, in_link, in_remote, true);
132         }
133 }
134