From a575eebbf87243c3a314929a2469db5bac0c7b42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 May 2021 23:09:29 -0700 Subject: [PATCH] altosuilib: Zap all flash when upgrading TeleGPS from pre-1.9.7 Old versions of TeleGPS firmware would end up spraying log data all over flash as they mis-computed the place to append new log data. When the right hardware is detected, a warning dialog will pop up and, if agreed to, the log storage flash will be completely erased before the firmware upgrade happens. Signed-off-by: Keith Packard --- altoslib/AltosLink.java | 14 ++++++ altosuilib/AltosFlashUI.java | 87 ++++++++++++++++++++++++++---------- 2 files changed, 77 insertions(+), 24 deletions(-) diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index b713b3dc..9346563d 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -507,6 +507,20 @@ public abstract class AltosLink implements Runnable { return ret; } + public void synchronize(int timeout) throws InterruptedException { + printf("v\n"); + for (;;) { + String line = get_reply(timeout); + + if (line == null) + break; + if (line.startsWith("software-version")) + break; + if (line.startsWith("altos-loader")) + break; + } + } + public void to_loader() throws InterruptedException { printf("X\n"); flush_output(); diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 6b78aea7..3665aaf1 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -80,6 +80,10 @@ public class AltosFlashUI "TeleShield" }; + private static final String[] log_erased_devices = { + "TeleGPS" + }; + private boolean is_pair_programmed() { if (file != null) { @@ -99,6 +103,17 @@ public class AltosFlashUI return false; } + private boolean is_log_erased() { + if (device != null) { + String name = device.toString(); + for (int i = 0; i < log_erased_devices.length; i++) { + if (name.startsWith(log_erased_devices[i])) + return true; + } + } + return false; + } + public void actionPerformed(ActionEvent e) { if (e.getSource() == cancel) { if (programmer != null) @@ -443,13 +458,20 @@ public class AltosFlashUI flash_task flasher; + boolean erase_answer; class open_task implements Runnable { AltosDevice device; Thread t; open_dialog dialog; + AltosLink link; public void do_exception(final Exception e) { + if (link != null) { + try { + link.close(); + } catch (Exception ex) {} + } SwingUtilities.invokeLater( new Runnable() { public void run() { @@ -467,27 +489,33 @@ public class AltosFlashUI }); } - public void do_failure() { - SwingUtilities.invokeLater( - new Runnable() { - public void run() { - try { dialog.open_failure(); } catch (Exception ex) { } - } - }); - } - - public void do_cancel() { + public boolean do_notify_erase(final AltosConfigData config_data) { + erase_answer = false; + final Semaphore erase_answer_done = new Semaphore(0); SwingUtilities.invokeLater( new Runnable() { public void run() { - try { dialog.open_cancel(); } catch (Exception ex) { } + int ret = JOptionPane.showConfirmDialog(dialog.owner, + String.format("Updating %s from firmware %s will erase stored data, continue?", + config_data.product, + config_data.version), + "Erase Stored Data?", + JOptionPane.YES_NO_OPTION); + erase_answer = ret == JOptionPane.YES_OPTION; + erase_answer_done.release(); } }); + try { + erase_answer_done.acquire(); + } catch (Exception ex) { + return false; + } + return erase_answer; } public void run () { + link = null; try { - AltosLink link = null; boolean new_device = false; for (;;) { @@ -510,6 +538,8 @@ public class AltosFlashUI throw new IOException(String.format("%s: open failed", device.toShortString())); + System.out.printf("Checking device ready\n"); + /* See if the link is usable already */ if (is_pair_programmed() || link.is_loader()) { System.out.printf("Device ready for use\n"); @@ -517,6 +547,24 @@ public class AltosFlashUI return; } + System.out.printf("Checking log erased\n"); + + if (is_log_erased()) { + System.out.printf("Fetching config data\n"); + AltosConfigData config_data = link.config_data(); + System.out.printf("version %s\n", config_data.version); + /* Completely erase TeleGPS flash when firmware is old */ + if (config_data.compare_version("1.9.7") < 0) + { + if (!do_notify_erase(config_data)) + throw new IOException(String.format("%s: not erasing log", + device.toShortString())); + System.out.printf("Erasing log\n"); + link.printf("Z DoIt\n"); + link.synchronize(120 * 1000); + } + } + java.util.List prev_devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); @@ -569,7 +617,10 @@ public class AltosFlashUI do_exception(fe); } catch (IOException ie) { do_exception (ie); + } catch (TimeoutException te) { + do_exception (te); } catch (InterruptedException ie) { + do_exception (ie); } } @@ -614,18 +665,6 @@ public class AltosFlashUI done = true; } - public void open_failure() { - System.out.printf("open_failure\n"); - setVisible(false); - done = true; - } - - public void open_cancel() { - System.out.printf("open_cancel\n"); - setVisible(false); - done = true; - } - public AltosLink do_open(open_task open) throws InterruptedException { this.open = open; setVisible(true); -- 2.30.2