Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
[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_7;
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         double                  frequency;
32         String                  callsign;
33
34         AltosListenerState      listener_state;
35         AltosConfigData         config_data;
36         AltosGPS                gps;
37
38         void start_link() throws InterruptedException, TimeoutException {
39                 if (remote) {
40                         link.set_radio_frequency(frequency);
41                         link.set_callsign(callsign);
42                         link.start_remote();
43                 } else
44                         link.flush_input();
45         }
46
47         boolean stop_link() throws InterruptedException, TimeoutException {
48                 if (remote)
49                         link.stop_remote();
50                 return link.reply_abort;
51         }
52
53         boolean update_state(AltosState state) throws InterruptedException, TimeoutException {
54                 boolean         worked = false;
55                 boolean         aborted = false;
56
57                 try {
58                         start_link();
59                         fetch.update_state(state);
60                         if (!link.has_error && !link.reply_abort)
61                                 worked = true;
62                 } finally {
63                         aborted = stop_link();
64                         if (worked) {
65                                 if (remote)
66                                         state.set_rssi(link.rssi(), 0);
67                                 listener_state.battery = link.monitor_battery();
68                         }
69                 }
70                 return aborted;
71         }
72
73         public void set_frequency(double in_frequency) {
74                 frequency = in_frequency;
75                 link.abort_reply();
76         }
77
78         public void set_callsign(String in_callsign) {
79                 callsign = in_callsign;
80                 link.abort_reply();
81         }
82
83         public void abort() throws InterruptedException {
84                 while (isAlive()) {
85                         interrupt();
86                         link.abort_reply();
87                         Thread.sleep(100);
88                 }
89                 join();
90         }
91
92         public void run() {
93                 AltosState state = new AltosState();
94                 try {
95                         for (;;) {
96                                 try {
97                                         link.config_data();
98                                         update_state(state);
99                                         listener.update(state, listener_state);
100                                 } catch (TimeoutException te) {
101                                 }
102                                 if (link.has_error || link.reply_abort) {
103                                         listener.failed();
104                                         break;
105                                 }
106                                 Thread.sleep(1000);
107                         }
108                 } catch (InterruptedException ie) {
109                 }
110                 try {
111                         link.close();
112                 } catch (InterruptedException ie) {
113                 }
114         }
115
116         public AltosIdleMonitor(AltosIdleMonitorListener in_listener, AltosLink in_link, boolean in_remote)
117                 throws FileNotFoundException, InterruptedException, TimeoutException {
118                 listener = in_listener;
119                 link = in_link;
120                 remote = in_remote;
121                 listener_state = new AltosListenerState();
122                 fetch = new AltosIdleFetch(link);
123         }
124 }