diff options
| author | Keith Packard <keithp@keithp.com> | 2013-11-12 14:37:57 +0900 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-11-12 14:37:57 +0900 | 
| commit | 0093d5b368669e0c324f8d9dfcd2f004de85ee5c (patch) | |
| tree | bf242fcab87507ad66d9abebe95315bcb9362504 /altoslib/AltosEepromDownload.java | |
| parent | 45db3076b257adcf2c9f69ed0927f09d94af7a50 (diff) | |
altosui, altoslib: Move eeprom download code to altoslib
This should make adding eeprom downloading to altosdroid easier
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altoslib/AltosEepromDownload.java')
| -rw-r--r-- | altoslib/AltosEepromDownload.java | 261 | 
1 files changed, 261 insertions, 0 deletions
diff --git a/altoslib/AltosEepromDownload.java b/altoslib/AltosEepromDownload.java new file mode 100644 index 00000000..542defee --- /dev/null +++ b/altoslib/AltosEepromDownload.java @@ -0,0 +1,261 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_2; + +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.concurrent.*; + +public class AltosEepromDownload implements Runnable { + +	AltosLink		link; +	boolean			remote; +	Thread			eeprom_thread; +	AltosEepromMonitor	monitor; + +	boolean			want_file; +	FileWriter		eeprom_file; +	LinkedList<String>	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'); +		} + +		for (String s : eeprom_pending) +			eeprom_file.write(s); +	} + +	private void CheckFile(boolean force) throws IOException { +		if (eeprom_file != null) +			return; +		if (force || (state.flight != 0 && want_file)) { +			AltosFile		eeprom_name; +			AltosGPS		gps = state.gps; + +			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; +			} +		} +	} + +	boolean			done; +	boolean			start; + +	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); +			else +				eeprom_pending.add(line); +		} +	} + +	void CaptureEeprom(AltosEepromChunk eechunk, int log_format) throws IOException, ParseException { +		boolean any_valid = false; +		boolean got_flight = false; + +		int record_length = 8; + +		state.set_serial(flights.config_data.serial); +		monitor.set_serial(flights.config_data.serial); + +		for (int i = 0; i < AltosEepromChunk.chunk_size && !done; i += record_length) { +			AltosEeprom r = eechunk.eeprom(i, log_format, state); + +			if (r == null) +				continue; + +			record_length = r.record_length(); + +			r.update_state(state); + +			if (!got_flight && state.flight != AltosLib.MISSING) +				monitor.set_flight(state.flight); + +			/* 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; +			} + +			if (state.gps != null) +				want_file = true; + +			if (r.valid) { +				any_valid = true; +				LogEeprom(r); +			} +		} +		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; + +		state = new AltosState(); + +		done = false; +		start = true; + +		if (flights.config_data.serial < 0) +			throw new IOException("no serial number found"); + +		/* Reset per-capture variables */ +		want_file = false; +		eeprom_file = null; +		eeprom_pending = new LinkedList<String>(); + +		/* 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; +				} +			} + +			CaptureEeprom (eechunk, log_format); +		} +		CheckFile(true); +		if (eeprom_file != null) { +			eeprom_file.flush(); +			eeprom_file.close(); +		} +	} + +	public void run () { +		try { +			boolean	failed = false; +			if (remote) +				link.start_remote(); + +			for (AltosEepromLog log : flights) { +				parse_exception = null; +				if (log.selected) { +					monitor.reset(); +					try { +						CaptureLog(log); +					} catch (ParseException e) { +						parse_exception = e; +					} +				} +				if (parse_exception != null) { +					failed = true; +					monitor.show_message(String.format("Flight %d download error\n%s\nValid log data saved", +									   log.flight, +									   parse_exception.getMessage()), +							     link.name, +							     AltosEepromMonitor.WARNING_MESSAGE); +				} +			} +			success = !failed; +		} catch (IOException ee) { +			monitor.show_message(ee.getLocalizedMessage(), +					     link.name, +					     AltosEepromMonitor.ERROR_MESSAGE); +		} catch (InterruptedException ie) { +			monitor.show_message(String.format("Connection to \"%s\" interrupted", +							   link.name), +					     "Connection Interrupted", +					     AltosEepromMonitor.ERROR_MESSAGE); +		} catch (TimeoutException te) { +			monitor.show_message(String.format("Connection to \"%s\" failed", +							   link.name), +					     "Connection Failed", +					     AltosEepromMonitor.ERROR_MESSAGE); +		} finally { +			if (remote) { +				try { +					link.stop_remote(); +				} catch (InterruptedException ie) { +				} +			} +			link.flush_output(); +		} +		monitor.done(success); +	} + +	public void start() { +		eeprom_thread = new Thread(this); +		eeprom_thread.start(); +	} + +	public AltosEepromDownload(AltosEepromMonitor given_monitor, +				   AltosLink given_link, +				   boolean given_remote, +				   AltosEepromList given_flights) { + +		monitor = given_monitor; +		link = given_link; +		remote = given_remote; +		flights = given_flights; +		success = false; + +		monitor.set_states(AltosLib.ao_flight_boost, AltosLib.ao_flight_landed); + +		monitor.set_thread(eeprom_thread); +		monitor.start(); +	} +}  | 
