From 97517ee585462c2d355f23f999fb8d9ebd908ec1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 26 Mar 2011 00:01:22 -0700 Subject: [PATCH] altosui: Allow TM config connection to be canceled. This leaves the config UI connection attempt running and pops up a dialog box when it takes 'too long' in the remote case so that users with Tm or Tn devices can bring up the UI, and then boot the Tm/Tn without needing to time things carefully. Signed-off-by: Keith Packard --- altosui/AltosConfig.java | 235 ++++++++++++++++++++++++++------------- altosui/AltosIgnite.java | 13 +-- altosui/AltosSerial.java | 95 ++++++++++++++-- 3 files changed, 247 insertions(+), 96 deletions(-) diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 47de6156..854d5384 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -109,86 +109,188 @@ public class AltosConfig implements ActionListener { void start_serial() throws InterruptedException { serial_started = true; - if (remote) { - serial_line.set_radio(); - serial_line.printf("p\nE 0\n"); - serial_line.flush_input(); - } + if (remote) + serial_line.start_remote(); } void stop_serial() throws InterruptedException { if (!serial_started) return; serial_started = false; - if (remote) { - serial_line.printf("~"); - serial_line.flush_output(); + if (remote) + serial_line.stop_remote(); + } + + void update_ui() { + config_ui.set_serial(serial.get()); + config_ui.set_product(product.get()); + config_ui.set_version(version.get()); + config_ui.set_main_deploy(main_deploy.get()); + config_ui.set_apogee_delay(apogee_delay.get()); + config_ui.set_radio_channel(radio_channel.get()); + config_ui.set_radio_calibration(radio_calibration.get()); + config_ui.set_flight_log_max(flight_log_max.get()); + config_ui.set_callsign(callsign.get()); + config_ui.set_clean(); + config_ui.make_visible(); + } + + void process_line(String line) { + if (line == null) { + System.out.printf("timeout\n"); + abort(); + return; } + if (line.equals("done")) { + System.out.printf("done\n"); + if (serial_line != null) + update_ui(); + return; + } + get_int(line, "serial-number", serial); + get_int(line, "Main deploy:", main_deploy); + get_int(line, "Apogee delay:", apogee_delay); + get_int(line, "Radio channel:", radio_channel); + get_int(line, "Radio cal:", radio_calibration); + get_int(line, "Max flight log:", flight_log_max); + get_string(line, "Callsign:", callsign); + get_string(line,"software-version", version); + get_string(line,"product", product); } - void get_data() throws InterruptedException, TimeoutException { - try { - start_serial(); - serial_line.printf("c s\nv\n"); - for (;;) { - String line = serial_line.get_reply(5000); - if (line == null) - throw new TimeoutException(); - get_int(line, "serial-number", serial); - get_int(line, "Main deploy:", main_deploy); - get_int(line, "Apogee delay:", apogee_delay); - get_int(line, "Radio channel:", radio_channel); - get_int(line, "Radio cal:", radio_calibration); - get_int(line, "Max flight log:", flight_log_max); - get_string(line, "Callsign:", callsign); - get_string(line,"software-version", version); - get_string(line,"product", product); - - /* signals the end of the version info */ - if (line.startsWith("software-version")) - break; + final static int serial_mode_read = 0; + final static int serial_mode_save = 1; + final static int serial_mode_reboot = 2; + + class SerialData implements Runnable { + AltosConfig config; + int serial_mode; + + void process_line(String line) { + config.process_line(line); + } + void callback(String in_line) { + final String line = in_line; + Runnable r = new Runnable() { + public void run() { + process_line(line); + } + }; + SwingUtilities.invokeLater(r); + } + + void get_data() { + try { + config.start_serial(); + config.serial_line.printf("c s\nv\n"); + for (;;) { + try { + String line = config.serial_line.get_reply(5000); + if (line == null) + stop_serial(); + callback(line); + if (line.startsWith("software-version")) + break; + } catch (Exception e) { + break; + } + } + } catch (InterruptedException ie) { + } finally { + try { + stop_serial(); + } catch (InterruptedException ie) { + } + } + callback("done"); + } + + void save_data() { + try { + start_serial(); + serial_line.printf("c m %d\n", main_deploy.get()); + serial_line.printf("c d %d\n", apogee_delay.get()); + if (!remote) { + serial_line.printf("c r %d\n", radio_channel.get()); + serial_line.printf("c f %d\n", radio_calibration.get()); + } + serial_line.printf("c c %s\n", callsign.get()); + if (flight_log_max.get() != 0) + serial_line.printf("c l %d\n", flight_log_max.get()); + serial_line.printf("c w\n"); + } catch (InterruptedException ie) { + } finally { + try { + stop_serial(); + } catch (InterruptedException ie) { + } + } + } + + void reboot() { + try { + start_serial(); + serial_line.printf("r eboot\n"); + serial_line.flush_output(); + } catch (InterruptedException ie) { + } finally { + try { + stop_serial(); + } catch (InterruptedException ie) { + } + serial_line.close(); } - } finally { - stop_serial(); + } + + public void run () { + switch (serial_mode) { + case serial_mode_save: + save_data(); + /* fall through ... */ + case serial_mode_read: + get_data(); + break; + case serial_mode_reboot: + reboot(); + break; + } + } + + public SerialData(AltosConfig in_config, int in_serial_mode) { + config = in_config; + serial_mode = in_serial_mode; } } + void run_serial_thread(int serial_mode) { + SerialData sd = new SerialData(this, serial_mode); + Thread st = new Thread(sd); + st.start(); + } + void init_ui () throws InterruptedException, TimeoutException { config_ui = new AltosConfigUI(owner, remote); config_ui.addActionListener(this); + serial_line.set_frame(owner); set_ui(); } void abort() { + serial_line.close(); + serial_line = null; JOptionPane.showMessageDialog(owner, String.format("Connection to \"%s\" failed", device.toShortString()), "Connection Failed", JOptionPane.ERROR_MESSAGE); - try { - stop_serial(); - } catch (InterruptedException ie) { - } - serial_line.close(); - serial_line = null; + config_ui.setVisible(false); } void set_ui() throws InterruptedException, TimeoutException { if (serial_line != null) - get_data(); - config_ui.set_serial(serial.get()); - config_ui.set_product(product.get()); - config_ui.set_version(version.get()); - config_ui.set_main_deploy(main_deploy.get()); - config_ui.set_apogee_delay(apogee_delay.get()); - config_ui.set_radio_channel(radio_channel.get()); - config_ui.set_radio_calibration(radio_calibration.get()); - config_ui.set_flight_log_max(flight_log_max.get()); - config_ui.set_callsign(callsign.get()); - config_ui.set_clean(); - } - - void run_dialog() { + run_serial_thread(serial_mode_read); + else + update_ui(); } void save_data() { @@ -198,25 +300,7 @@ public class AltosConfig implements ActionListener { radio_calibration.set(config_ui.radio_calibration()); flight_log_max.set(config_ui.flight_log_max()); callsign.set(config_ui.callsign()); - try { - start_serial(); - serial_line.printf("c m %d\n", main_deploy.get()); - serial_line.printf("c d %d\n", apogee_delay.get()); - if (!remote) { - serial_line.printf("c r %d\n", radio_channel.get()); - serial_line.printf("c f %d\n", radio_calibration.get()); - } - serial_line.printf("c c %s\n", callsign.get()); - if (flight_log_max.get() != 0) - serial_line.printf("c l %d\n", flight_log_max.get()); - serial_line.printf("c w\n"); - } catch (InterruptedException ie) { - } finally { - try { - stop_serial(); - } catch (InterruptedException ie) { - } - } + run_serial_thread(serial_mode_save); } public void actionPerformed(ActionEvent e) { @@ -224,17 +308,11 @@ public class AltosConfig implements ActionListener { try { if (cmd.equals("Save")) { save_data(); - set_ui(); } else if (cmd.equals("Reset")) { set_ui(); } else if (cmd.equals("Reboot")) { - if (serial_line != null) { - start_serial(); - serial_line.printf("r eboot\n"); - serial_line.flush_output(); - stop_serial(); - serial_line.close(); - } + if (serial_line != null) + run_serial_thread(serial_mode_reboot); } else if (cmd.equals("Close")) { if (serial_line != null) serial_line.close(); @@ -267,7 +345,6 @@ public class AltosConfig implements ActionListener { remote = true; try { init_ui(); - config_ui.make_visible(); } catch (InterruptedException ie) { abort(); } catch (TimeoutException te) { diff --git a/altosui/AltosIgnite.java b/altosui/AltosIgnite.java index 3cbd8a75..d3638140 100644 --- a/altosui/AltosIgnite.java +++ b/altosui/AltosIgnite.java @@ -36,11 +36,8 @@ public class AltosIgnite { private void start_serial() throws InterruptedException { serial_started = true; - if (remote) { - serial.set_radio(); - serial.printf("p\nE 0\n"); - serial.flush_input(); - } + if (remote) + serial.start_remote(); } private void stop_serial() throws InterruptedException { @@ -49,10 +46,8 @@ public class AltosIgnite { serial_started = false; if (serial == null) return; - if (remote) { - serial.printf("~"); - serial.flush_output(); - } + if (remote) + serial.stop_remote(); } class string_ref { diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index a8ba66bd..88b38bb1 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -25,6 +25,11 @@ import java.lang.*; import java.io.*; import java.util.concurrent.*; import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; import libaltosJNI.*; @@ -36,7 +41,7 @@ import libaltosJNI.*; public class AltosSerial implements Runnable { - static List devices_opened = Collections.synchronizedList(new LinkedList()); + static java.util.List devices_opened = Collections.synchronizedList(new LinkedList()); AltosDevice device; SWIGTYPE_p_altos_file altos; @@ -52,6 +57,7 @@ public class AltosSerial implements Runnable { static boolean debug; boolean remote; LinkedList pending_output = new LinkedList(); + Frame frame; static void set_debug(boolean new_debug) { debug = new_debug; @@ -126,6 +132,59 @@ public class AltosSerial implements Runnable { } } + boolean abort; + JDialog timeout_dialog; + boolean timeout_started = false; + + private void stop_timeout_dialog() { + System.out.printf("stop_timeout_dialog\n"); + Runnable r = new Runnable() { + public void run() { + if (timeout_dialog != null) + timeout_dialog.setVisible(false); + } + }; + SwingUtilities.invokeLater(r); + } + + private void start_timeout_dialog_internal() { + System.out.printf("Creating timeout dialog\n"); + Object[] options = { "Cancel" }; + + JOptionPane pane = new JOptionPane(); + pane.setMessage(String.format("Connecting to %s", device.getPath())); + pane.setOptions(options); + pane.setInitialValue(null); + + timeout_dialog = pane.createDialog(frame, "Connecting..."); + + timeout_dialog.setVisible(true); + + Object o = pane.getValue(); + if (o == null) + return; + if (options[0].equals(o)) + abort = true; + } + + private boolean check_timeout() { + if (!timeout_started && frame != null) { + timeout_started = true; + System.out.printf("Starting timeout dialog\n"); + if (SwingUtilities.isEventDispatchThread()) { + start_timeout_dialog_internal(); + } else { + Runnable r = new Runnable() { + public void run() { + start_timeout_dialog_internal(); + } + }; + SwingUtilities.invokeLater(r); + } + } + return abort; + } + public void flush_input() { flush_output(); boolean got_some; @@ -156,10 +215,21 @@ public class AltosSerial implements Runnable { public String get_reply(int timeout) throws InterruptedException { flush_output(); - AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS); - if (line == null) - return null; - return line.line; + if (remote) { + timeout = 300; + System.out.printf("Doing remote timout\n"); + } + abort = false; + timeout_started = false; + for (;;) { + AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS); + if (line != null) { + stop_timeout_dialog(); + return line.line; + } + if (!remote || check_timeout()) + return null; + } } public void add_monitor(LinkedBlockingQueue q) { @@ -289,16 +359,25 @@ public class AltosSerial implements Runnable { public void stop_remote() { if (debug) System.out.printf("stop remote\n"); - flush_input(); - printf ("~"); - flush_output(); + try { + flush_input(); + } finally { + System.out.printf("Sending tilde\n"); + printf ("~\n"); + flush_output(); + } remote = false; } + public void set_frame(Frame in_frame) { + frame = in_frame; + } + public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { device = in_device; line = ""; monitor_mode = false; + frame = null; telemetry = Altos.ao_telemetry_full; monitors = new LinkedList> (); reply_queue = new LinkedBlockingQueue (); -- 2.30.2