X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosLink.java;h=6d510563c5d32622bfbc3cfb854da885c21b4f27;hp=a39204ac3ba26e8892f6c79658625ca7f036067a;hb=3fe5c2f9fc01258d45c20070e9874d76bc6c8c07;hpb=9dcb4e2ab60ecf0cc7371c1b1a620be952fa8776 diff --git a/altoslib/AltosLink.java b/altoslib/AltosLink.java index a39204ac..6d510563 100644 --- a/altoslib/AltosLink.java +++ b/altoslib/AltosLink.java @@ -17,13 +17,16 @@ package org.altusmetrum.AltosLib; -import java.lang.*; import java.io.*; import java.util.concurrent.*; import java.util.*; -import java.text.*; -public abstract class AltosLink { +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(); @@ -60,16 +63,116 @@ public abstract class AltosLink { return null; } - public String get_reply(int timeout) throws InterruptedException { + public String get_reply() throws InterruptedException { + return get_reply(5000); + } + + + public abstract boolean can_cancel_reply(); + public abstract boolean show_reply_timeout(); + public abstract void hide_reply_timeout(); + + public boolean reply_abort; + public int in_reply; + + boolean reply_timeout_shown = false; + + private boolean check_reply_timeout() { + if (!reply_timeout_shown) + reply_timeout_shown = show_reply_timeout(); + return reply_abort; + } + + private void cleanup_reply_timeout() { + if (reply_timeout_shown) { + reply_timeout_shown = false; + hide_reply_timeout(); + } + } + + + public void run () { + int c; + byte[] line_bytes = null; + int line_count = 0; + try { - return get_reply_no_dialog(timeout); - } catch (TimeoutException te) { - return null; + for (;;) { + c = getchar(); + if (Thread.interrupted()) { + if (debug) + System.out.printf("INTERRUPTED\n"); + break; + } + if (c == ERROR) { + if (debug) + System.out.printf("ERROR\n"); + add_telem (new AltosLine()); + add_reply (new AltosLine()); + break; + } + if (c == TIMEOUT) { + if (debug) + System.out.printf("TIMEOUT\n"); + continue; + } + if (c == '\r') + continue; + synchronized(this) { + if (c == '\n') { + if (line_count != 0) { + add_bytes(line_bytes, line_count); + line_count = 0; + } + } else { + if (line_bytes == null) { + line_bytes = new byte[256]; + } else if (line_count == line_bytes.length) { + byte[] new_line_bytes = new byte[line_count * 2]; + System.arraycopy(line_bytes, 0, new_line_bytes, 0, line_count); + line_bytes = new_line_bytes; + } + line_bytes[line_count] = (byte) c; + line_count++; + } + } + } + } catch (InterruptedException e) { } } - public String get_reply() throws InterruptedException { - return get_reply(5000); + public String get_reply(int timeout) throws InterruptedException { + boolean can_cancel = can_cancel_reply(); + String reply = null; + + if (!can_cancel && remote) + System.out.printf("Uh-oh, reading remote serial device from swing thread\n"); + + if (remote && can_cancel) + timeout = 500; + try { + ++in_reply; + + flush_output(); + + reply_abort = false; + reply_timeout_shown = false; + for (;;) { + AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS); + if (line != null) { + cleanup_reply_timeout(); + reply = line.line; + break; + } + if (!remote || !can_cancel || check_reply_timeout()) { + reply = null; + break; + } + } + } finally { + --in_reply; + } + return reply; } public void add_telem(AltosLine line) throws InterruptedException { @@ -83,6 +186,14 @@ public abstract class AltosLink { reply_queue.put (line); } + public void abort_reply() { + try { + add_telem (new AltosLine()); + add_reply (new AltosLine()); + } catch (InterruptedException e) { + } + } + public void add_string(String line) throws InterruptedException { if (line.startsWith("TELEM") || line.startsWith("VERSION") || line.startsWith("CRC")) { add_telem(new AltosLine(line)); @@ -124,7 +235,10 @@ public abstract class AltosLink { public void flush_input() throws InterruptedException { - flush_input(100); + if (remote) + flush_input(500); + else + flush_input(100); }