diff options
Diffstat (limited to 'altoslib/AltosLink.java')
| -rw-r--r-- | altoslib/AltosLink.java | 130 | 
1 files changed, 110 insertions, 20 deletions
diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index 159ebfe1..ee1f9785 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -package org.altusmetrum.altoslib_1; +package org.altusmetrum.altoslib_2;  import java.io.*;  import java.util.concurrent.*; @@ -26,23 +26,28 @@ public abstract class AltosLink implements Runnable {  	public final static int ERROR = -1;  	public final static int TIMEOUT = -2; -	public abstract int getchar(); -	public abstract void print(String data); -	public abstract void close(); +	public abstract int getchar() throws InterruptedException; +	public abstract void print(String data) throws InterruptedException; +	public abstract void putchar(byte c); +	public abstract void close() throws InterruptedException;  	public static boolean debug = false;  	public static void set_debug(boolean in_debug) { debug = in_debug; } + +	public boolean has_error; +  	LinkedList<String> pending_output = new LinkedList<String>();  	public LinkedList<LinkedBlockingQueue<AltosLine>> monitors = new LinkedList<LinkedBlockingQueue<AltosLine>> ();;  	public LinkedBlockingQueue<AltosLine> reply_queue = new LinkedBlockingQueue<AltosLine>(); +	public LinkedBlockingQueue<byte[]> binary_queue = new LinkedBlockingQueue<byte[]>(); -	public void add_monitor(LinkedBlockingQueue<AltosLine> q) { +	public synchronized void add_monitor(LinkedBlockingQueue<AltosLine> q) {  		set_monitor(true);  		monitors.add(q);  	} -	public void remove_monitor(LinkedBlockingQueue<AltosLine> q) { +	public synchronized void remove_monitor(LinkedBlockingQueue<AltosLine> q) {  		monitors.remove(q);  		if (monitors.isEmpty())  			set_monitor(false); @@ -52,7 +57,11 @@ public abstract class AltosLink implements Runnable {  		String	line = String.format(format, arguments);  		if (debug)  			pending_output.add(line); -		print(line); +		try { +			print(line); +		} catch (InterruptedException ie) { + +		}  	}  	public String get_reply_no_dialog(int timeout) throws InterruptedException, TimeoutException { @@ -90,6 +99,7 @@ public abstract class AltosLink implements Runnable {  		}  	} +	private int	len_read = 0;  	public void run () {  		int c; @@ -100,13 +110,12 @@ public abstract class AltosLink implements Runnable {  			for (;;) {  				c = getchar();  				if (Thread.interrupted()) { -					if (debug) -						System.out.printf("INTERRUPTED\n");  					break;  				}  				if (c == ERROR) {  					if (debug)  						System.out.printf("ERROR\n"); +					has_error = true;  					add_telem (new AltosLine());  					add_reply (new AltosLine());  					break; @@ -116,10 +125,10 @@ public abstract class AltosLink implements Runnable {  						System.out.printf("TIMEOUT\n");  					continue;  				} -				if (c == '\r') +				if (c == '\r' && len_read == 0)  					continue;  				synchronized(this) { -					if (c == '\n') { +					if (c == '\n' && len_read == 0) {  						if (line_count != 0) {  							add_bytes(line_bytes, line_count);  							line_count = 0; @@ -134,6 +143,11 @@ public abstract class AltosLink implements Runnable {  						}  						line_bytes[line_count] = (byte) c;  						line_count++; +						if (len_read !=0 && line_count == len_read) { +							add_binary(line_bytes, line_count); +							line_count = 0; +							len_read = 0; +						}  					}  				}  			} @@ -141,6 +155,7 @@ public abstract class AltosLink implements Runnable {  		}  	} +  	public String get_reply(int timeout) throws InterruptedException {  		boolean	can_cancel = can_cancel_reply();  		String	reply = null; @@ -175,6 +190,38 @@ public abstract class AltosLink implements Runnable {  		return reply;  	} +	public byte[] get_binary_reply(int timeout, int len) throws InterruptedException { +		boolean	can_cancel = can_cancel_reply(); +		byte[] bytes = null; + +		synchronized(this) { +			len_read = len; +		} +		try { +			++in_reply; + +			flush_output(); + +			reply_abort = false; +			reply_timeout_shown = false; +			for (;;) { +				bytes = binary_queue.poll(timeout, TimeUnit.MILLISECONDS); +				if (bytes != null) { +					cleanup_reply_timeout(); +					break; +				} +				if (!remote || !can_cancel || check_reply_timeout()) { +					bytes = null; +					break; +				} +			} +			 +		} finally { +			--in_reply; +		} +		return bytes; +	} +  	public void add_telem(AltosLine line) throws InterruptedException {  		for (int e = 0; e < monitors.size(); e++) {  			LinkedBlockingQueue<AltosLine> q = monitors.get(e); @@ -190,7 +237,7 @@ public abstract class AltosLink implements Runnable {  		try {  			add_telem (new AltosLine());  			add_reply (new AltosLine()); -		} catch (InterruptedException e) { +		} catch (InterruptedException ie) {  		}  	} @@ -216,6 +263,22 @@ public abstract class AltosLink implements Runnable {  		add_string(line);  	} +	public void add_binary(byte[] bytes, int len) throws InterruptedException { +		byte[] dup = new byte[len]; + +		if (debug) +			System.out.printf ("\t\t\t\t\t%d:", len); +		for(int i = 0; i < len; i++) { +			dup[i] = bytes[i]; +			if (debug) +				System.out.printf(" %02x", dup[i]); +		} +		if (debug) +			System.out.printf("\n"); + +		binary_queue.put(dup); +	} +  	public void flush_output() {  		for (String s : pending_output)  			System.out.print(s); @@ -252,6 +315,8 @@ public abstract class AltosLink implements Runnable {  	public String callsign;  	AltosConfigData	config_data; +	private Object config_data_lock = new Object(); +  	private int telemetry_len() {  		return AltosLib.telemetry_len(telemetry);  	} @@ -325,9 +390,11 @@ public abstract class AltosLink implements Runnable {  	}  	public AltosConfigData config_data() throws InterruptedException, TimeoutException { -		if (config_data == null) -			config_data = new AltosConfigData(this); -		return config_data; +		synchronized(config_data_lock) { +			if (config_data == null) +				config_data = new AltosConfigData(this); +			return config_data; +		}  	}  	public void set_callsign(String callsign) { @@ -336,6 +403,29 @@ public abstract class AltosLink implements Runnable {  		flush_output();  	} +	public boolean is_loader() throws InterruptedException { +		boolean	ret = false; +		printf("v\n"); +		for (;;) { +			String line = get_reply(); + +			if (line == null) +				return false; +			if (line.startsWith("software-version")) +				break; +			if (line.startsWith("altos-loader")) +				ret = true; +		} +		return ret; +	} + +	public void to_loader() throws InterruptedException { +		printf("X\n"); +		flush_output(); +		close(); +		Thread.sleep(1000); +	} +  	public boolean remote;  	public int serial;  	public String name; @@ -398,8 +488,8 @@ public abstract class AltosLink implements Runnable {  		return config_data.has_monitor_battery();  	} -	public double monitor_battery() { -		int monitor_batt = AltosRecord.MISSING; +	public double monitor_battery() throws InterruptedException { +		int monitor_batt = AltosLib.MISSING;  		if (config_data.has_monitor_battery()) {  			try { @@ -412,16 +502,16 @@ public abstract class AltosLink implements Runnable {  				}  				i++;  			} -			} catch (InterruptedException ie) {  			} catch (TimeoutException te) {  			}  		} -		if (monitor_batt == AltosRecord.MISSING) -			return AltosRecord.MISSING; +		if (monitor_batt == AltosLib.MISSING) +			return AltosLib.MISSING;  		return AltosConvert.cc_battery_to_voltage(monitor_batt);  	}  	public AltosLink() {  		callsign = ""; +		has_error = false;  	}  }  | 
