X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosEepromDownload.java;h=74912ed4bac7218b8d9a2462360e4e8c1acc32dc;hp=1b04316715809b1e42be683748112761b6e720aa;hb=17e20a6d2dab1f4bd1375bfd9e1c5230ee2c1119;hpb=b19a648b667c298d2d9d5ed4ee9db661be058d1a diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java index 1b043167..74912ed4 100644 --- a/altoslib/AltosEepromDownload.java +++ b/altoslib/AltosEepromDownload.java @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,7 +16,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_2; +package org.altusmetrum.altoslib_11; import java.io.*; import java.util.*; @@ -29,183 +30,160 @@ public class AltosEepromDownload implements Runnable { Thread eeprom_thread; AltosEepromMonitor monitor; - boolean want_file; - FileWriter eeprom_file; - LinkedList eeprom_pending; - AltosEepromList flights; - boolean success; - ParseException parse_exception; - AltosState state; - - private void FlushPending() throws IOException { - for (String s : flights.config_data) { - eeprom_file.write(s); - eeprom_file.write('\n'); - } + String parse_errors; + + private boolean has_gps_date(AltosState state) { + if (state == null) + return false; - for (String s : eeprom_pending) - eeprom_file.write(s); + AltosGPS gps = state.gps; + + return gps != null && + gps.year != AltosLib.MISSING && + gps.month != AltosLib.MISSING && + gps.day != AltosLib.MISSING; } - private void CheckFile(boolean force) throws IOException { - if (eeprom_file != null) - return; - if (force || (state.flight != 0 && want_file)) { - AltosFile eeprom_name; + private AltosFile MakeFile(int serial, int flight, AltosState state) throws IOException { + AltosFile eeprom_name; + + if (has_gps_date(state)) { AltosGPS gps = state.gps; + eeprom_name = new AltosFile(gps.year, gps.month, gps.day, + serial, flight, "eeprom"); + } else + eeprom_name = new AltosFile(serial, flight, "eeprom"); - if (gps != null && - gps.year != AltosLib.MISSING && - gps.month != AltosLib.MISSING && - gps.day != AltosLib.MISSING) - { - eeprom_name = new AltosFile(gps.year, gps.month, gps.day, - state.serial, state.flight, "eeprom"); - } else - eeprom_name = new AltosFile(state.serial, state.flight, "eeprom"); - - eeprom_file = new FileWriter(eeprom_name); - if (eeprom_file != null) { - monitor.set_filename(eeprom_name.getName()); - FlushPending(); - eeprom_pending = null; - } - } + return eeprom_name; } boolean done; - boolean start; + int prev_state; + int state_block; + + void LogError(String error) { + if (parse_errors != null) + parse_errors.concat(error.concat("\n")); + else + parse_errors = error; + } + + class BlockCache extends Hashtable { + AltosEepromLog log; + + AltosEepromChunk get(int start, boolean add) throws TimeoutException, InterruptedException { + if (contains(start)) + return super.get(start); + AltosEepromChunk eechunk = new AltosEepromChunk(link, start, start == log.start_block); + if (add) + put(start, eechunk); + return eechunk; + } - void LogEeprom(AltosEeprom r) throws IOException { - if (r.cmd != AltosLib.AO_LOG_INVALID) { - String line = r.string(); - if (eeprom_file != null) - eeprom_file.write(line); + public BlockCache(AltosEepromLog log) { + this.log = log; + } + } + + int FindLastLog(AltosEepromLog log, BlockCache cache) throws TimeoutException, InterruptedException { + int low = log.start_block; + int high = log.end_block - 1; + + while (low <= high) { + int mid = (high + low) / 2; + + if (!cache.get(mid, true).erased()) + low = mid + 1; else - eeprom_pending.add(line); + high = mid - 1; } + return low; } - void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { - boolean any_valid = false; - boolean got_flight = false; + void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { + int block, state_block = 0; + int log_format = flights.config_data.log_format; + BlockCache cache = new BlockCache(log); - int record_length = 8; + done = false; - state.set_serial(flights.config_data.serial); - monitor.set_serial(flights.config_data.serial); + if (flights.config_data.serial < 0) + throw new IOException("no serial number found"); - for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { - AltosEeprom r = eechunk.eeprom(i, log_format, state); + /* Set serial number in the monitor dialog window */ + monitor.set_serial(log.serial); + monitor.set_flight(log.flight); - if (r == null) - continue; + int start_block = log.start_block; + int end_block = FindLastLog(log, cache); - record_length = r.record_length(); + monitor.set_max(end_block - start_block - 1); - r.update_state(state); + ArrayList data = new ArrayList(); - if (!got_flight && state.flight != AltosLib.MISSING) - monitor.set_flight(state.flight); + /* Now scan the eeprom, reading blocks of data to create a byte array of data */ - /* Monitor state transitions to update display */ - if (state.state != AltosLib.ao_flight_invalid && - state.state <= AltosLib.ao_flight_landed) - { - if (state.state > AltosLib.ao_flight_pad) - want_file = true; - if (state.state == AltosLib.ao_flight_landed) - done = true; - } + for (block = start_block; block < end_block; block++) { + monitor.set_block(block - start_block); - if (state.gps != null) - want_file = true; + AltosEepromChunk eechunk = cache.get(block, false); - if (r.valid) { - any_valid = true; - LogEeprom(r); - } + for (int i = 0; i < eechunk.data.length; i++) + data.add((byte) eechunk.data[i]); } - if (!any_valid) - done = true; - CheckFile(false); - } - - void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException, ParseException { - int block, state_block = 0; - int log_format = flights.config_data.log_format; + /* Construct our internal representation of the eeprom data */ + AltosEepromNew eeprom = new AltosEepromNew(flights.config_data, data); - state = new AltosState(); + /* Now see if we can't actually parse the resulting + * file to generate a better filename. Note that this + * doesn't need to work; we'll still save the data using + * a less accurate name. + */ + AltosEepromRecordSet set = new AltosEepromRecordSet(eeprom); - done = false; - start = true; + AltosState state = new AltosState(); - if (flights.config_data.serial < 0) - throw new IOException("no serial number found"); + for (AltosState s : set) { + state = s; + if (state.gps != null) + break; + } - /* Reset per-capture variables */ - want_file = false; - eeprom_file = null; - eeprom_pending = new LinkedList(); + AltosFile f = MakeFile(flights.config_data.serial, log.flight, state); - /* Set serial number in the monitor dialog window */ - /* Now scan the eeprom, reading blocks of data and converting to .eeprom file form */ - - state_block = log.start_block; - for (block = log.start_block; !done && block < log.end_block; block++) { - monitor.set_value(state.state_name(), - state.state, - block - state_block, - block - log.start_block); - - AltosEepromChunk eechunk = new AltosEepromChunk(link, block, block == log.start_block); - - /* - * Guess what kind of data is there if the device - * didn't tell us - */ - - if (log_format == AltosLib.AO_LOG_FORMAT_UNKNOWN) { - if (block == log.start_block) { - if (eechunk.data(0) == AltosLib.AO_LOG_FLIGHT) - log_format = AltosLib.AO_LOG_FORMAT_FULL; - else - log_format = AltosLib.AO_LOG_FORMAT_TINY; - } - } + monitor.set_filename(f.toString()); - CaptureEeprom (eechunk, log_format); - } - CheckFile(true); - if (eeprom_file != null) { - eeprom_file.flush(); - eeprom_file.close(); - } + FileWriter w = new FileWriter(f); + + eeprom.write(w); + w.close(); } public void run () { + boolean success = false; + try { boolean failed = false; if (remote) link.start_remote(); for (AltosEepromLog log : flights) { - parse_exception = null; + parse_errors = null; if (log.selected) { monitor.reset(); try { CaptureLog(log); } catch (ParseException e) { - parse_exception = e; + LogError(e.getMessage()); } } - if (parse_exception != null) { + if (parse_errors != null) { failed = true; - monitor.show_message(String.format("Flight %d download error\n%s\nValid log data saved", + monitor.show_message(String.format("Flight %d download error. Valid log data saved\n%s", log.flight, - parse_exception.getMessage()), + parse_errors), link.name, AltosEepromMonitor.WARNING_MESSAGE); } @@ -252,9 +230,6 @@ public class AltosEepromDownload implements Runnable { link = given_link; remote = given_remote; flights = given_flights; - success = false; - - monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed); monitor.start(); }