/* * Copyright © 2010 Keith Packard * * 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. */ /* * Deal with TeleDongle on a serial port */ package altosui; import java.io.*; import java.util.*; import java.awt.*; import javax.swing.*; import org.altusmetrum.altoslib_2.*; import org.altusmetrum.altosuilib_1.*; import libaltosJNI.*; /* * This class reads from the serial port and places each received * line in a queue. Dealing with that queue is left up to other * threads. */ public class AltosSerial extends AltosLink { static java.util.List devices_opened = Collections.synchronizedList(new LinkedList()); AltosDevice device; SWIGTYPE_p_altos_file altos; Thread input_thread; String line; byte[] line_bytes; int line_count; Frame frame; public int getchar() { if (altos == null) return ERROR; return libaltos.altos_getchar(altos, 0); } public void flush_output() { super.flush_output(); if (altos != null) { if (libaltos.altos_flush(altos) != 0) close_serial(); } } JDialog timeout_dialog; private void start_timeout_dialog_internal() { Object[] options = { "Cancel" }; JOptionPane pane = new JOptionPane(); pane.setMessage(String.format("Connecting to %s, %7.3f MHz as %s", device.toShortString(), frequency, callsign)); pane.setOptions(options); pane.setInitialValue(null); timeout_dialog = pane.createDialog(frame, "Connecting..."); timeout_dialog.setVisible(true); Object o = pane.getValue(); if (o == null) return; if (options[0].equals(o)) reply_abort = true; timeout_dialog.dispose(); timeout_dialog = null; } /* * These are required by the AltosLink implementation */ public boolean can_cancel_reply() { /* * Can cancel any replies not called from the dispatch thread */ return !SwingUtilities.isEventDispatchThread(); } public boolean show_reply_timeout() { if (!SwingUtilities.isEventDispatchThread() && frame != null) { Runnable r = new Runnable() { public void run() { start_timeout_dialog_internal(); } }; SwingUtilities.invokeLater(r); return true; } return false; } public void hide_reply_timeout() { Runnable r = new Runnable() { public void run() { timeout_dialog.setVisible(false); } }; SwingUtilities.invokeLater(r); } private void close_serial() { synchronized (devices_opened) { devices_opened.remove(device.getPath()); } if (altos != null) { libaltos.altos_free(altos); altos = null; } abort_reply(); } public void close() { if (remote) { try { stop_remote(); } catch (InterruptedException ie) { } } if (in_reply != 0) System.out.printf("Uh-oh. Closing active serial device\n"); close_serial(); if (input_thread != null) { try { input_thread.interrupt(); input_thread.join(); } catch (InterruptedException e) { } input_thread = null; } if (debug) System.out.printf("Closing %s\n", device.getPath()); } private void putc(char c) { if (altos != null) if (libaltos.altos_putchar(altos, c) != 0) { close_serial(); } } public void putchar(byte c) { if (altos != null) { if (debug) System.out.printf(" %02x", (int) c & 0xff); if (libaltos.altos_putchar(altos, (char) c) != 0) { close_serial(); } } } public void print(String data) { for (int i = 0; i < data.length(); i++) putc(data.charAt(i)); } private void open() throws FileNotFoundException, AltosSerialInUseException { synchronized (devices_opened) { if (devices_opened.contains(device.getPath())) throw new AltosSerialInUseException(device); devices_opened.add(device.getPath()); } altos = device.open(); if (altos == null) { final String message = device.getErrorString(); close(); throw new FileNotFoundException(String.format("%s (%s)", device.toShortString(), message)); } if (debug) System.out.printf("Open %s\n", device.getPath()); input_thread = new Thread(this); input_thread.start(); print("~\nE 0\n"); set_monitor(false); flush_output(); } public void set_frame(Frame in_frame) { frame = in_frame; } public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { device = in_device; frame = null; serial = device.getSerial(); name = device.toShortString(); open(); } }