summaryrefslogtreecommitdiff
path: root/altosui
diff options
context:
space:
mode:
Diffstat (limited to 'altosui')
-rw-r--r--altosui/Altos.java2
-rw-r--r--altosui/AltosBTDevice.java7
-rw-r--r--altosui/AltosCSVUI.java2
-rw-r--r--altosui/AltosConfig.java3
-rw-r--r--altosui/AltosConfigureUI.java33
-rw-r--r--altosui/AltosDataChooser.java2
-rw-r--r--altosui/AltosDevice.java1
-rw-r--r--altosui/AltosDeviceDialog.java36
-rw-r--r--altosui/AltosEepromDownload.java12
-rw-r--r--altosui/AltosEepromManage.java3
-rw-r--r--altosui/AltosFlashUI.java4
-rw-r--r--altosui/AltosIgniteUI.java3
-rw-r--r--altosui/AltosLanded.java4
-rw-r--r--altosui/AltosLaunch.java201
-rw-r--r--altosui/AltosLaunchUI.java517
-rw-r--r--altosui/AltosPreferences.java39
-rw-r--r--altosui/AltosScanUI.java6
-rw-r--r--altosui/AltosSerial.java4
-rw-r--r--altosui/AltosUI.java20
-rw-r--r--altosui/AltosUSBDevice.java7
-rw-r--r--altosui/Makefile.am5
-rw-r--r--altosui/libaltos/libaltos.c175
-rw-r--r--altosui/libaltos/libaltos.h13
23 files changed, 1009 insertions, 90 deletions
diff --git a/altosui/Altos.java b/altosui/Altos.java
index e4f974f9..aa2fd77a 100644
--- a/altosui/Altos.java
+++ b/altosui/Altos.java
@@ -498,5 +498,5 @@ public class Altos {
public final static String bt_product_telebt = bt_product_telebt();
-// public static AltosBTKnown bt_known = new AltosBTKnown();
+ public static AltosBTKnown bt_known = new AltosBTKnown();
}
diff --git a/altosui/AltosBTDevice.java b/altosui/AltosBTDevice.java
index 7a876c25..55b8f8fc 100644
--- a/altosui/AltosBTDevice.java
+++ b/altosui/AltosBTDevice.java
@@ -42,6 +42,13 @@ public class AltosBTDevice extends altos_bt_device implements AltosDevice {
return getAddr();
}
+ public String getErrorString() {
+ altos_error error = new altos_error();
+
+ libaltos.altos_get_last_error(error);
+ return String.format("%s (%d)", error.getString(), error.getCode());
+ }
+
public int getSerial() {
String name = getName();
if (name == null)
diff --git a/altosui/AltosCSVUI.java b/altosui/AltosCSVUI.java
index e1b6002d..a212409e 100644
--- a/altosui/AltosCSVUI.java
+++ b/altosui/AltosCSVUI.java
@@ -99,7 +99,7 @@ public class AltosCSVUI
writer.close();
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(frame,
- file.getName(),
+ ee.getMessage(),
"Cannot open file",
JOptionPane.ERROR_MESSAGE);
}
diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java
index 122ebecc..93def70d 100644
--- a/altosui/AltosConfig.java
+++ b/altosui/AltosConfig.java
@@ -480,8 +480,7 @@ public class AltosConfig implements ActionListener {
}
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(owner,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ee.getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} catch (AltosSerialInUseException si) {
diff --git a/altosui/AltosConfigureUI.java b/altosui/AltosConfigureUI.java
index bcb9636b..980068c0 100644
--- a/altosui/AltosConfigureUI.java
+++ b/altosui/AltosConfigureUI.java
@@ -52,8 +52,7 @@ public class AltosConfigureUI
JRadioButton serial_debug;
-// BLUETOOTH
-// JButton manage_bluetooth;
+ JButton manage_bluetooth;
JButton manage_frequencies;
final static String[] font_size_names = { "Small", "Medium", "Large" };
@@ -241,19 +240,18 @@ public class AltosConfigureUI
c.anchor = GridBagConstraints.WEST;
pane.add(serial_debug, c);
-// BLUETOOTH
-// manage_bluetooth = new JButton("Manage Bluetooth");
-// manage_bluetooth.addActionListener(new ActionListener() {
-// public void actionPerformed(ActionEvent e) {
-// AltosBTManage.show(owner, Altos.bt_known);
-// }
-// });
-// c.gridx = 0;
-// c.gridy = row++;
-// c.gridwidth = 2;
-// c.fill = GridBagConstraints.NONE;
-// c.anchor = GridBagConstraints.WEST;
-// pane.add(manage_bluetooth, c);
+ manage_bluetooth = new JButton("Manage Bluetooth");
+ manage_bluetooth.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ AltosBTManage.show(owner, Altos.bt_known);
+ }
+ });
+ c.gridx = 0;
+ c.gridy = row;
+ c.gridwidth = 2;
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.WEST;
+ pane.add(manage_bluetooth, c);
manage_frequencies = new JButton("Manage Frequencies");
manage_frequencies.addActionListener(new ActionListener() {
@@ -262,9 +260,8 @@ public class AltosConfigureUI
}
});
manage_frequencies.setToolTipText("Configure which values are shown in frequency menus");
-// BLUETOOTH
-// c.gridx = 2;
- c.gridx = 1;
+ c.gridx = 2;
+ c.gridx = 2;
c.gridy = row++;
c.gridwidth = 2;
c.fill = GridBagConstraints.NONE;
diff --git a/altosui/AltosDataChooser.java b/altosui/AltosDataChooser.java
index 15de05c2..d81ca6d1 100644
--- a/altosui/AltosDataChooser.java
+++ b/altosui/AltosDataChooser.java
@@ -61,7 +61,7 @@ public class AltosDataChooser extends JFileChooser {
}
} catch (FileNotFoundException fe) {
JOptionPane.showMessageDialog(frame,
- filename,
+ fe.getMessage(),
"Cannot open file",
JOptionPane.ERROR_MESSAGE);
}
diff --git a/altosui/AltosDevice.java b/altosui/AltosDevice.java
index 3357c550..1b5c1a91 100644
--- a/altosui/AltosDevice.java
+++ b/altosui/AltosDevice.java
@@ -26,5 +26,6 @@ public interface AltosDevice {
public abstract int getSerial();
public abstract String getPath();
public abstract boolean matchProduct(int product);
+ public abstract String getErrorString();
public SWIGTYPE_p_altos_file open();
}
diff --git a/altosui/AltosDeviceDialog.java b/altosui/AltosDeviceDialog.java
index fa9587bc..610bb73e 100644
--- a/altosui/AltosDeviceDialog.java
+++ b/altosui/AltosDeviceDialog.java
@@ -30,8 +30,7 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
private JList list;
private JButton cancel_button;
private JButton select_button;
-// BLUETOOTH
-// private JButton manage_bluetooth_button;
+ private JButton manage_bluetooth_button;
private Frame frame;
private int product;
@@ -42,17 +41,15 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
private AltosDevice[] devices() {
java.util.List<AltosDevice> usb_devices = AltosUSBDevice.list(product);
int num_devices = usb_devices.size();
-// BLUETOOTH
-// java.util.List<AltosDevice> bt_devices = Altos.bt_known.list(product);
-// num_devices += bt_devices.size();
+ java.util.List<AltosDevice> bt_devices = Altos.bt_known.list(product);
+ num_devices += bt_devices.size();
AltosDevice[] devices = new AltosDevice[num_devices];
for (int i = 0; i < usb_devices.size(); i++)
devices[i] = usb_devices.get(i);
-// BLUETOOTH
-// int off = usb_devices.size();
-// for (int j = 0; j < bt_devices.size(); j++)
-// devices[off + j] = bt_devices.get(j);
+ int off = usb_devices.size();
+ for (int j = 0; j < bt_devices.size(); j++)
+ devices[off + j] = bt_devices.get(j);
return devices;
}
@@ -75,10 +72,9 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
cancel_button.setActionCommand("cancel");
cancel_button.addActionListener(this);
-// BLUETOOTH
-// manage_bluetooth_button = new JButton("Manage Bluetooth");
-// manage_bluetooth_button.setActionCommand("manage");
-// manage_bluetooth_button.addActionListener(this);
+ manage_bluetooth_button = new JButton("Manage Bluetooth");
+ manage_bluetooth_button.setActionCommand("manage");
+ manage_bluetooth_button.addActionListener(this);
select_button = new JButton("Select");
select_button.setActionCommand("select");
@@ -152,8 +148,7 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
buttonPane.add(Box.createHorizontalGlue());
buttonPane.add(cancel_button);
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
-// BLUETOOTH
-// buttonPane.add(manage_bluetooth_button);
+ buttonPane.add(manage_bluetooth_button);
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPane.add(select_button);
@@ -173,12 +168,11 @@ public class AltosDeviceDialog extends JDialog implements ActionListener {
public void actionPerformed(ActionEvent e) {
if ("select".equals(e.getActionCommand()))
value = (AltosDevice)(list.getSelectedValue());
-// BLUETOOTH
-// if ("manage".equals(e.getActionCommand())) {
-// AltosBTManage.show(frame, Altos.bt_known);
-// update_devices();
-// return;
-// }
+ if ("manage".equals(e.getActionCommand())) {
+ AltosBTManage.show(frame, Altos.bt_known);
+ update_devices();
+ return;
+ }
setVisible(false);
}
diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java
index 358ad337..e7e52466 100644
--- a/altosui/AltosEepromDownload.java
+++ b/altosui/AltosEepromDownload.java
@@ -248,6 +248,10 @@ public class AltosEepromDownload implements Runnable {
done = true;
}
+ void CaptureTelemetry(AltosEepromChunk eechunk) throws IOException {
+
+ }
+
void CaptureLog(AltosEepromLog log) throws IOException, InterruptedException, TimeoutException {
int block, state_block = 0;
int log_format = flights.config_data.log_format;
@@ -300,10 +304,10 @@ public class AltosEepromDownload implements Runnable {
extension = "eeprom";
CaptureTiny(eechunk);
break;
-// case Altos.AO_LOG_FORMAT_TELEMETRY:
-// extension = "telem";
-// CaptureTelemetry(eechunk);
-// break;
+ case Altos.AO_LOG_FORMAT_TELEMETRY:
+ extension = "telem";
+ CaptureTelemetry(eechunk);
+ break;
case Altos.AO_LOG_FORMAT_TELESCIENCE:
extension = "science";
CaptureTeleScience(eechunk);
diff --git a/altosui/AltosEepromManage.java b/altosui/AltosEepromManage.java
index 2e520628..083c7372 100644
--- a/altosui/AltosEepromManage.java
+++ b/altosui/AltosEepromManage.java
@@ -219,8 +219,7 @@ public class AltosEepromManage implements ActionListener {
t.start();
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(frame,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ee.getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} catch (AltosSerialInUseException si) {
diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java
index 3874b500..3956ff20 100644
--- a/altosui/AltosFlashUI.java
+++ b/altosui/AltosFlashUI.java
@@ -200,8 +200,8 @@ public class AltosFlashUI
void exception (Exception e) {
if (e instanceof FileNotFoundException) {
JOptionPane.showMessageDialog(frame,
- "Cannot open image",
- file.toString(),
+ ((FileNotFoundException) e).getMessage(),
+ "Cannot open file",
JOptionPane.ERROR_MESSAGE);
} else if (e instanceof AltosSerialInUseException) {
JOptionPane.showMessageDialog(frame,
diff --git a/altosui/AltosIgniteUI.java b/altosui/AltosIgniteUI.java
index c11a8614..b215c228 100644
--- a/altosui/AltosIgniteUI.java
+++ b/altosui/AltosIgniteUI.java
@@ -122,8 +122,7 @@ public class AltosIgniteUI
void ignite_exception(Exception e) {
if (e instanceof FileNotFoundException) {
JOptionPane.showMessageDialog(owner,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ((FileNotFoundException) e).getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} else if (e instanceof AltosSerialInUseException) {
diff --git a/altosui/AltosLanded.java b/altosui/AltosLanded.java
index 50e6b542..4dd9a2dd 100644
--- a/altosui/AltosLanded.java
+++ b/altosui/AltosLanded.java
@@ -250,7 +250,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
FileInputStream in = new FileInputStream(file);
records = new AltosTelemetryIterable(in);
} else {
- throw new FileNotFoundException();
+ throw new FileNotFoundException(filename);
}
try {
new AltosGraphUI(records, filename);
@@ -259,7 +259,7 @@ public class AltosLanded extends JComponent implements AltosFlightDisplay, Actio
}
} catch (FileNotFoundException fe) {
JOptionPane.showMessageDialog(null,
- filename,
+ fe.getMessage(),
"Cannot open file",
JOptionPane.ERROR_MESSAGE);
}
diff --git a/altosui/AltosLaunch.java b/altosui/AltosLaunch.java
new file mode 100644
index 00000000..77f681b8
--- /dev/null
+++ b/altosui/AltosLaunch.java
@@ -0,0 +1,201 @@
+/*
+ * 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 altosui;
+
+import java.io.*;
+import java.util.concurrent.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import javax.swing.table.*;
+import javax.swing.event.*;
+
+public class AltosLaunch {
+ AltosDevice device;
+ AltosSerial serial;
+ boolean serial_started;
+ int launcher_serial;
+ int launcher_channel;
+ int rssi;
+
+ final static int Unknown = -1;
+ final static int Good = 0;
+ final static int Bad = 1;
+
+ int armed;
+ int igniter;
+
+ private void start_serial() throws InterruptedException {
+ serial_started = true;
+ }
+
+ private void stop_serial() throws InterruptedException {
+ if (!serial_started)
+ return;
+ serial_started = false;
+ if (serial == null)
+ return;
+ }
+
+ class string_ref {
+ String value;
+
+ public String get() {
+ return value;
+ }
+ public void set(String i) {
+ value = i;
+ }
+ public string_ref() {
+ value = null;
+ }
+ }
+
+ private boolean get_string(String line, String label, string_ref s) {
+ if (line.startsWith(label)) {
+ String quoted = line.substring(label.length()).trim();
+
+ if (quoted.startsWith("\""))
+ quoted = quoted.substring(1);
+ if (quoted.endsWith("\""))
+ quoted = quoted.substring(0,quoted.length()-1);
+ s.set(quoted);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean status() throws InterruptedException, TimeoutException {
+ boolean ok = false;
+ if (serial == null)
+ return false;
+ string_ref status_name = new string_ref();
+ start_serial();
+ serial.printf("l %d %d\n", launcher_serial, launcher_channel);
+ for (;;) {
+ String line = serial.get_reply(20000);
+ if (line == null)
+ throw new TimeoutException();
+ if (get_string(line, "Rssi: ", status_name)) {
+ try {
+ rssi = Altos.fromdec(status_name.get());
+ } catch (NumberFormatException ne) {
+ }
+ break;
+ } else if (get_string(line, "Armed: ", status_name)) {
+ armed = Good;
+ String status = status_name.get();
+ if (status.startsWith("igniter good"))
+ igniter = Good;
+ else if (status.startsWith("igniter bad"))
+ igniter = Bad;
+ else
+ igniter = Unknown;
+ ok = true;
+ } else if (get_string(line, "Disarmed: ", status_name)) {
+ armed = Bad;
+ if (status_name.get().startsWith("igniter good"))
+ igniter = Good;
+ else if (status_name.get().startsWith("igniter bad"))
+ igniter = Bad;
+ else
+ igniter = Unknown;
+ ok = true;
+ } else if (get_string(line, "Error ", status_name)) {
+ armed = Unknown;
+ igniter = Unknown;
+ ok = false;
+ break;
+ }
+ }
+ stop_serial();
+ if (!ok) {
+ armed = Unknown;
+ igniter = Unknown;
+ }
+ return ok;
+ }
+
+ public static String status_string(int status) {
+ switch (status) {
+ case Good:
+ return "good";
+ case Bad:
+ return "open";
+ }
+ return "unknown";
+ }
+
+ public void arm() {
+ if (serial == null)
+ return;
+ try {
+ start_serial();
+ serial.printf("a %d %d\n", launcher_serial, launcher_channel);
+ serial.flush_output();
+ } catch (InterruptedException ie) {
+ } finally {
+ try {
+ stop_serial();
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+
+ public void fire() {
+ if (serial == null)
+ return;
+ try {
+ start_serial();
+ serial.printf("i %d %d\n", launcher_serial, launcher_channel);
+ serial.flush_output();
+ } catch (InterruptedException ie) {
+ } finally {
+ try {
+ stop_serial();
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+
+ public void close() {
+ try {
+ stop_serial();
+ } catch (InterruptedException ie) {
+ }
+ serial.close();
+ serial = null;
+ }
+
+ public void set_frame(Frame frame) {
+ serial.set_frame(frame);
+ }
+
+ public void set_remote(int in_serial, int in_channel) {
+ launcher_serial = in_serial;
+ launcher_channel = in_channel;
+ }
+
+ public AltosLaunch(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException {
+
+ device = in_device;
+ serial = new AltosSerial(device);
+ }
+} \ No newline at end of file
diff --git a/altosui/AltosLaunchUI.java b/altosui/AltosLaunchUI.java
new file mode 100644
index 00000000..47365e03
--- /dev/null
+++ b/altosui/AltosLaunchUI.java
@@ -0,0 +1,517 @@
+/*
+ * 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 altosui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import javax.swing.table.*;
+import javax.swing.event.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.util.prefs.*;
+import java.util.concurrent.*;
+
+class FireButton extends JButton {
+ protected void processMouseEvent(MouseEvent e) {
+ super.processMouseEvent(e);
+ switch (e.getID()) {
+ case MouseEvent.MOUSE_PRESSED:
+ if (actionListener != null)
+ actionListener.actionPerformed(new ActionEvent(this, e.getID(), "fire_down"));
+ break;
+ case MouseEvent.MOUSE_RELEASED:
+ if (actionListener != null)
+ actionListener.actionPerformed(new ActionEvent(this, e.getID(), "fire_up"));
+ break;
+ }
+ }
+
+ public FireButton(String s) {
+ super(s);
+ }
+}
+
+public class AltosLaunchUI
+ extends JDialog
+ implements ActionListener
+{
+ AltosDevice device;
+ JFrame owner;
+ JLabel label;
+
+ int radio_channel;
+ JLabel radio_channel_label;
+ JTextField radio_channel_text;
+
+ int launcher_serial;
+ JLabel launcher_serial_label;
+ JTextField launcher_serial_text;
+
+ int launcher_channel;
+ JLabel launcher_channel_label;
+ JTextField launcher_channel_text;
+
+ JLabel armed_label;
+ JLabel armed_status_label;
+ JLabel igniter;
+ JLabel igniter_status_label;
+ JToggleButton arm;
+ FireButton fire;
+ javax.swing.Timer arm_timer;
+ javax.swing.Timer fire_timer;
+
+ boolean firing;
+ boolean armed;
+ int armed_status;
+ int igniter_status;
+ int rssi;
+
+ final static int arm_timeout = 1 * 1000;
+ final static int fire_timeout = 250;
+
+ int armed_count;
+
+ LinkedBlockingQueue<String> command_queue;
+
+ class LaunchHandler implements Runnable {
+ AltosLaunch launch;
+ JFrame owner;
+
+ void send_exception(Exception e) {
+ final Exception f_e = e;
+ Runnable r = new Runnable() {
+ public void run() {
+ launch_exception(f_e);
+ }
+ };
+ SwingUtilities.invokeLater(r);
+ }
+
+ public void run () {
+ try {
+ launch = new AltosLaunch(device);
+ } catch (Exception e) {
+ send_exception(e);
+ return;
+ }
+ launch.set_frame(owner);
+ launch.set_remote(launcher_serial, launcher_channel);
+
+ for (;;) {
+ Runnable r;
+
+ try {
+ String command = command_queue.take();
+ String reply = null;
+
+ if (command.equals("get_status")) {
+ launch.status();
+ reply = "status";
+ armed_status = launch.armed;
+ igniter_status = launch.igniter;
+ rssi = launch.rssi;
+ } else if (command.equals("set_remote")) {
+ launch.set_remote(launcher_serial, launcher_channel);
+ reply = "remote set";
+ } else if (command.equals("arm")) {
+ launch.arm();
+ reply = "armed";
+ } else if (command.equals("fire")) {
+ launch.fire();
+ reply = "fired";
+ } else if (command.equals("quit")) {
+ launch.close();
+ break;
+ } else {
+ throw new ParseException(String.format("invalid command %s", command), 0);
+ }
+ final String f_reply = reply;
+ r = new Runnable() {
+ public void run() {
+ launch_reply(f_reply);
+ }
+ };
+ SwingUtilities.invokeLater(r);
+ } catch (Exception e) {
+ send_exception(e);
+ }
+ }
+ }
+
+ public LaunchHandler(JFrame in_owner) {
+ owner = in_owner;
+ }
+ }
+
+ void launch_exception(Exception e) {
+ if (e instanceof FileNotFoundException) {
+ JOptionPane.showMessageDialog(owner,
+ ((FileNotFoundException) e).getMessage(),
+ "Cannot open target device",
+ JOptionPane.ERROR_MESSAGE);
+ } else if (e instanceof AltosSerialInUseException) {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Device \"%s\" already in use",
+ device.toShortString()),
+ "Device in use",
+ JOptionPane.ERROR_MESSAGE);
+ } else if (e instanceof IOException) {
+ IOException ee = (IOException) e;
+ JOptionPane.showMessageDialog(owner,
+ device.toShortString(),
+ ee.getLocalizedMessage(),
+ JOptionPane.ERROR_MESSAGE);
+ } else {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Connection to \"%s\" failed",
+ device.toShortString()),
+ "Connection Failed",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ close();
+ }
+
+ void launch_reply(String reply) {
+ if (reply == null)
+ return;
+ if (reply.equals("remote set"))
+ poll_launch_status();
+ if (reply.equals("status")) {
+ set_launch_status();
+ }
+ }
+
+ void set_arm_text() {
+ if (arm.isSelected())
+ arm.setText(String.format("%d", armed_count));
+ else
+ arm.setText("Arm");
+ }
+
+ void start_arm_timer() {
+ armed_count = 30;
+ set_arm_text();
+ }
+
+ void stop_arm_timer() {
+ armed_count = 0;
+ armed = false;
+ arm.setSelected(false);
+ fire.setEnabled(false);
+ set_arm_text();
+ }
+
+ void cancel () {
+ fire.setEnabled(false);
+ firing = false;
+ stop_arm_timer();
+ }
+
+ void send_command(String command) {
+ try {
+ command_queue.put(command);
+ } catch (Exception ex) {
+ launch_exception(ex);
+ }
+ }
+
+ boolean getting_status = false;
+
+ void set_launch_status() {
+ getting_status = false;
+ armed_status_label.setText(String.format("\"%s\"", AltosLaunch.status_string(armed_status)));
+ igniter_status_label.setText(String.format("\"%s\"", AltosLaunch.status_string(igniter_status)));
+ }
+
+ void poll_launch_status() {
+ if (!getting_status && !firing && !armed) {
+ getting_status = true;
+ send_command("get_status");
+ }
+ }
+
+ void fired() {
+ firing = false;
+ cancel();
+ }
+
+ void close() {
+ send_command("quit");
+ arm_timer.stop();
+ setVisible(false);
+ dispose();
+ }
+
+ void tick_arm_timer() {
+ if (armed_count > 0) {
+ --armed_count;
+ if (armed_count <= 0) {
+ armed_count = 0;
+ cancel();
+ } else {
+ if (!firing) {
+ send_command("arm");
+ set_arm_text();
+ }
+ }
+ }
+ poll_launch_status();
+ }
+
+ void arm() {
+ if (arm.isSelected()) {
+ fire.setEnabled(true);
+ start_arm_timer();
+ if (!firing)
+ send_command("arm");
+ armed = true;
+ } else
+ cancel();
+ }
+
+ void fire_more() {
+ if (firing)
+ send_command("fire");
+ }
+
+ void fire_down() {
+ if (arm.isEnabled() && arm.isSelected() && armed_count > 0) {
+ firing = true;
+ fire_more();
+ fire_timer.restart();
+ }
+ }
+
+ void fire_up() {
+ firing = false;
+ fire_timer.stop();
+ }
+
+ void set_radio() {
+ try {
+ radio_channel = Integer.parseInt(radio_channel_text.getText());
+ } catch (NumberFormatException ne) {
+ radio_channel_text.setText(String.format("%d", radio_channel));
+ }
+ }
+
+ void set_serial() {
+ try {
+ launcher_serial = Integer.parseInt(launcher_serial_text.getText());
+ AltosPreferences.set_launcher_serial(launcher_serial);
+ send_command("set_remote");
+ } catch (NumberFormatException ne) {
+ launcher_serial_text.setText(String.format("%d", launcher_serial));
+ }
+ }
+
+ void set_channel() {
+ try {
+ launcher_channel = Integer.parseInt(launcher_channel_text.getText());
+ AltosPreferences.set_launcher_serial(launcher_channel);
+ send_command("set_remote");
+ } catch (NumberFormatException ne) {
+ launcher_channel_text.setText(String.format("%d", launcher_channel));
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ System.out.printf("cmd %s\n", cmd);
+ if (cmd.equals("armed") || cmd.equals("igniter")) {
+ stop_arm_timer();
+ }
+
+ if (cmd.equals("arm"))
+ arm();
+ if (cmd.equals("tick_arm"))
+ tick_arm_timer();
+ if (cmd.equals("close"))
+ close();
+ if (cmd.equals("fire_down"))
+ fire_down();
+ if (cmd.equals("fire_up"))
+ fire_up();
+ if (cmd.equals("tick_fire"))
+ fire_more();
+ if (cmd.equals("new_serial"))
+ set_serial();
+ if (cmd.equals("new_channel"))
+ set_channel();
+ }
+
+ /* A window listener to catch closing events and tell the config code */
+ class ConfigListener extends WindowAdapter {
+ AltosLaunchUI ui;
+
+ public ConfigListener(AltosLaunchUI this_ui) {
+ ui = this_ui;
+ }
+
+ public void windowClosing(WindowEvent e) {
+ ui.actionPerformed(new ActionEvent(e.getSource(),
+ ActionEvent.ACTION_PERFORMED,
+ "close"));
+ }
+ }
+
+ private boolean open() {
+ command_queue = new LinkedBlockingQueue<String>();
+
+ device = AltosDeviceDialog.show(owner, Altos.product_any);
+ if (device != null) {
+ LaunchHandler handler = new LaunchHandler(owner);
+ Thread t = new Thread(handler);
+ t.start();
+ return true;
+ }
+ return false;
+ }
+
+ public AltosLaunchUI(JFrame in_owner) {
+
+ launcher_channel = AltosPreferences.launcher_channel();
+ launcher_serial = AltosPreferences.launcher_serial();
+ owner = in_owner;
+ armed_status = AltosLaunch.Unknown;
+ igniter_status = AltosLaunch.Unknown;
+
+ if (!open())
+ return;
+
+ Container pane = getContentPane();
+ GridBagConstraints c = new GridBagConstraints();
+ Insets i = new Insets(4,4,4,4);
+
+ arm_timer = new javax.swing.Timer(arm_timeout, this);
+ arm_timer.setActionCommand("tick_arm");
+ arm_timer.restart();
+
+ fire_timer = new javax.swing.Timer(fire_timeout, this);
+ fire_timer.setActionCommand("tick_fire");
+
+ owner = in_owner;
+
+ pane.setLayout(new GridBagLayout());
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 1;
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.gridwidth = 2;
+ c.anchor = GridBagConstraints.CENTER;
+ label = new JLabel ("Launch Controller");
+ pane.add(label, c);
+
+ c.gridx = 0;
+ c.gridy = 1;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ launcher_serial_label = new JLabel("Launcher Serial");
+ pane.add(launcher_serial_label, c);
+
+ c.gridx = 1;
+ c.gridy = 1;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ launcher_serial_text = new JTextField(7);
+ launcher_serial_text.setText(String.format("%d", launcher_serial));
+ launcher_serial_text.setActionCommand("new_serial");
+ launcher_serial_text.addActionListener(this);
+ pane.add(launcher_serial_text, c);
+
+ c.gridx = 0;
+ c.gridy = 2;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ launcher_channel_label = new JLabel("Launcher Channel");
+ pane.add(launcher_channel_label, c);
+
+ c.gridx = 1;
+ c.gridy = 2;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ launcher_channel_text = new JTextField(7);
+ launcher_channel_text.setText(String.format("%d", launcher_channel));
+ launcher_channel_text.setActionCommand("new_channel");
+ launcher_channel_text.addActionListener(this);
+ pane.add(launcher_channel_text, c);
+
+ c.gridx = 0;
+ c.gridy = 3;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ armed_label = new JLabel ("Armed");
+ pane.add(armed_label, c);
+
+ c.gridx = 1;
+ c.gridy = 3;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ armed_status_label = new JLabel();
+ pane.add(armed_status_label, c);
+
+ c.gridx = 0;
+ c.gridy = 4;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ igniter = new JLabel ("Igniter");
+ pane.add(igniter, c);
+
+ c.gridx = 1;
+ c.gridy = 4;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.WEST;
+ igniter_status_label = new JLabel();
+ pane.add(igniter_status_label, c);
+
+ c.gridx = 0;
+ c.gridy = 5;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+ arm = new JToggleButton ("Arm");
+ pane.add(arm, c);
+ arm.addActionListener(this);
+ arm.setActionCommand("arm");
+ arm.setEnabled(true);
+
+ c.gridx = 1;
+ c.gridy = 5;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+ fire = new FireButton ("Fire");
+ fire.setEnabled(false);
+ pane.add(fire, c);
+ fire.addActionListener(this);
+ fire.setActionCommand("fire");
+
+ pack();
+ setLocationRelativeTo(owner);
+
+ addWindowListener(new ConfigListener(this));
+
+ setVisible(true);
+ }
+} \ No newline at end of file
diff --git a/altosui/AltosPreferences.java b/altosui/AltosPreferences.java
index 716559ab..48aed441 100644
--- a/altosui/AltosPreferences.java
+++ b/altosui/AltosPreferences.java
@@ -58,6 +58,12 @@ class AltosPreferences {
/* font size preferences name */
final static String fontSizePreference = "FONT-SIZE";
+ /* Launcher serial preference name */
+ final static String launcherSerialPreference = "LAUNCHER-SERIAL";
+
+ /* Launcher channel prefernce name */
+ final static String launcherChannelPreference = "LAUNCHER-CHANNEL";
+
/* Default logdir is ~/TeleMetrum */
final static String logdirName = "TeleMetrum";
@@ -143,6 +149,9 @@ class AltosPreferences {
node.put(String.format(description_format, i), frequencies[i].description);
}
}
+ static int launcher_serial;
+
+ static int launcher_channel;
public static void init() {
preferences = Preferences.userRoot().node("/org/altusmetrum/altosui");
@@ -176,6 +185,10 @@ class AltosPreferences {
font_size = preferences.getInt(fontSizePreference, Altos.font_size_medium);
Altos.set_fonts(font_size);
+ launcher_serial = preferences.getInt(launcherSerialPreference, 0);
+
+ launcher_channel = preferences.getInt(launcherChannelPreference, 0);
+
String firmwaredir_string = preferences.get(firmwaredirPreference, null);
if (firmwaredir_string != null)
firmwaredir = new File(firmwaredir_string);
@@ -390,6 +403,32 @@ class AltosPreferences {
return serial_debug;
}
+ public static void set_launcher_serial(int new_launcher_serial) {
+ launcher_serial = new_launcher_serial;
+ System.out.printf("set launcher serial to %d\n", new_launcher_serial);
+ synchronized (preferences) {
+ preferences.putInt(launcherSerialPreference, launcher_serial);
+ flush_preferences();
+ }
+ }
+
+ public static int launcher_serial() {
+ return launcher_serial;
+ }
+
+ public static void set_launcher_channel(int new_launcher_channel) {
+ launcher_channel = new_launcher_channel;
+ System.out.printf("set launcher channel to %d\n", new_launcher_channel);
+ synchronized (preferences) {
+ preferences.putInt(launcherChannelPreference, launcher_channel);
+ flush_preferences();
+ }
+ }
+
+ public static int launcher_channel() {
+ return launcher_channel;
+ }
+
public static Preferences bt_devices() {
return preferences.node("bt_devices");
}
diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java
index bce4b32c..df5c51d4 100644
--- a/altosui/AltosScanUI.java
+++ b/altosui/AltosScanUI.java
@@ -130,8 +130,7 @@ public class AltosScanUI
void scan_exception(Exception e) {
if (e instanceof FileNotFoundException) {
JOptionPane.showMessageDialog(owner,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ((FileNotFoundException) e).getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} else if (e instanceof AltosSerialInUseException) {
@@ -326,8 +325,7 @@ public class AltosScanUI
return true;
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(owner,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ee.getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} catch (AltosSerialInUseException si) {
diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java
index 0a531aa9..4cf306d0 100644
--- a/altosui/AltosSerial.java
+++ b/altosui/AltosSerial.java
@@ -323,8 +323,10 @@ public class AltosSerial implements Runnable {
}
altos = device.open();
if (altos == null) {
+ final String message = device.getErrorString();
close();
- throw new FileNotFoundException(device.toShortString());
+ throw new FileNotFoundException(String.format("%s (%s)",
+ device.toShortString(), message));
}
if (debug)
System.out.printf("Open %s\n", device.getPath());
diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java
index 27c41838..3e5bcf43 100644
--- a/altosui/AltosUI.java
+++ b/altosui/AltosUI.java
@@ -52,8 +52,7 @@ public class AltosUI extends JFrame {
new AltosFlightUI(voice, reader, device.getSerial());
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(AltosUI.this,
- String.format("Cannot open device \"%s\"",
- device.toShortString()),
+ ee.getMessage(),
"Cannot open target device",
JOptionPane.ERROR_MESSAGE);
} catch (AltosSerialInUseException si) {
@@ -210,6 +209,13 @@ public class AltosUI extends JFrame {
});
b.setToolTipText("Check flight readiness of altimeter in idle mode");
+ b = addButton(3, 2, "Launch Controller");
+ b.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ LaunchController();
+ }
+ });
+
setTitle("AltOS");
pane.doLayout();
@@ -272,6 +278,10 @@ public class AltosUI extends JFrame {
new AltosSiteMapPreload(AltosUI.this);
}
+ void LaunchController() {
+ new AltosLaunchUI(AltosUI.this);
+ }
+
/*
* Replay a flight from telemetry data
*/
@@ -345,7 +355,7 @@ public class AltosUI extends JFrame {
else
return new AltosTelemetryIterable(in);
} catch (FileNotFoundException fe) {
- System.out.printf("Cannot open '%s'\n", filename);
+ System.out.printf("%s\n", fe.getMessage());
return null;
}
}
@@ -355,7 +365,7 @@ public class AltosUI extends JFrame {
try {
return new AltosCSV(file);
} catch (FileNotFoundException fe) {
- System.out.printf("Cannot open '%s'\n", filename);
+ System.out.printf("%s\n", fe.getMessage());
return null;
}
}
@@ -365,7 +375,7 @@ public class AltosUI extends JFrame {
try {
return new AltosKML(file);
} catch (FileNotFoundException fe) {
- System.out.printf("Cannot open '%s'\n", filename);
+ System.out.printf("%s\n", fe.getMessage());
return null;
}
}
diff --git a/altosui/AltosUSBDevice.java b/altosui/AltosUSBDevice.java
index dc746a64..b11a3934 100644
--- a/altosui/AltosUSBDevice.java
+++ b/altosui/AltosUSBDevice.java
@@ -39,6 +39,13 @@ public class AltosUSBDevice extends altos_device implements AltosDevice {
}
+ public String getErrorString() {
+ altos_error error = new altos_error();
+
+ libaltos.altos_get_last_error(error);
+ return String.format("%s (%d)", error.getString(), error.getCode());
+ }
+
public SWIGTYPE_p_altos_file open() {
return libaltos.altos_open(this);
}
diff --git a/altosui/Makefile.am b/altosui/Makefile.am
index ba1c830c..c4d1e611 100644
--- a/altosui/Makefile.am
+++ b/altosui/Makefile.am
@@ -68,6 +68,8 @@ altosui_JAVA = \
AltosIdleMonitorUI.java \
AltosIgnite.java \
AltosIgniteUI.java \
+ AltosLaunch.java \
+ AltosLaunchUI.java \
AltosInfoTable.java \
AltosKML.java \
AltosLanded.java \
@@ -116,7 +118,8 @@ altosui_JAVA = \
AltosGraphUI.java \
AltosDataChooser.java \
AltosVersion.java \
- AltosVoice.java
+ AltosVoice.java \
+ $(altosui_BT)
JFREECHART_CLASS= \
jfreechart.jar
diff --git a/altosui/libaltos/libaltos.c b/altosui/libaltos/libaltos.c
index d1f445bd..48e00a44 100644
--- a/altosui/libaltos/libaltos.c
+++ b/altosui/libaltos/libaltos.c
@@ -49,6 +49,22 @@ altos_fini(void)
{
}
+static struct altos_error last_error;
+
+static void
+altos_set_last_error(int code, char *string)
+{
+ last_error.code = code;
+ strncpy(last_error.string, string, sizeof (last_error.string) -1);
+ last_error.string[sizeof(last_error.string)-1] = '\0';
+}
+
+PUBLIC void
+altos_get_last_error(struct altos_error *error)
+{
+ *error = last_error;
+}
+
#ifdef DARWIN
#undef USE_POLL
@@ -96,6 +112,12 @@ struct altos_file {
int in_read;
};
+static void
+altos_set_last_posix_error(void)
+{
+ altos_set_last_error(errno, strerror(errno));
+}
+
PUBLIC struct altos_file *
altos_open(struct altos_device *device)
{
@@ -103,12 +125,18 @@ altos_open(struct altos_device *device)
int ret;
struct termios term;
- if (!file)
+ if (!file) {
+ altos_set_last_posix_error();
return NULL;
+ }
+
+// altos_set_last_error(12, "yeah yeah, failed again");
+// free(file);
+// return NULL;
file->fd = open(device->path, O_RDWR | O_NOCTTY);
if (file->fd < 0) {
- perror(device->path);
+ altos_set_last_posix_error();
free(file);
return NULL;
}
@@ -117,7 +145,7 @@ altos_open(struct altos_device *device)
#else
file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
if (file->out_fd < 0) {
- perror(device->path);
+ altos_set_last_posix_error();
close(file->fd);
free(file);
return NULL;
@@ -125,7 +153,7 @@ altos_open(struct altos_device *device)
#endif
ret = tcgetattr(file->fd, &term);
if (ret < 0) {
- perror("tcgetattr");
+ altos_set_last_posix_error();
close(file->fd);
#ifndef USE_POLL
close(file->out_fd);
@@ -143,7 +171,7 @@ altos_open(struct altos_device *device)
#endif
ret = tcsetattr(file->fd, TCSAFLUSH, &term);
if (ret < 0) {
- perror("tcsetattr");
+ altos_set_last_posix_error();
close(file->fd);
#ifndef USE_POLL
close(file->out_fd);
@@ -195,8 +223,10 @@ altos_flush(struct altos_file *file)
#else
ret = write (file->out_fd, file->out_data, file->out_used);
#endif
- if (ret < 0)
+ if (ret < 0) {
+ altos_set_last_posix_error();
return -errno;
+ }
if (ret) {
memmove(file->out_data, file->out_data + ret,
file->out_used - ret);
@@ -248,7 +278,7 @@ altos_fill(struct altos_file *file, int timeout)
fd[1].events = POLLIN;
ret = poll(fd, 2, timeout);
if (ret < 0) {
- perror("altos_getchar");
+ altos_set_last_posix_error();
return LIBALTOS_ERROR;
}
if (ret == 0)
@@ -261,7 +291,7 @@ altos_fill(struct altos_file *file, int timeout)
{
ret = read(file->fd, file->in_data, USB_BUF_SIZE);
if (ret < 0) {
- perror("altos_getchar");
+ altos_set_last_posix_error();
return LIBALTOS_ERROR;
}
file->in_read = 0;
@@ -598,7 +628,6 @@ altos_list_finish(struct altos_list *usbdevs)
free(usbdevs);
}
-#if HAS_BLUETOOTH
struct altos_bt_list {
inquiry_info *ii;
int sock;
@@ -701,8 +730,10 @@ altos_bt_open(struct altos_bt_device *device)
if (!file)
goto no_file;
file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- if (file->fd < 0)
+ if (file->fd < 0) {
+ altos_set_last_posix_error();
goto no_sock;
+ }
addr.rc_family = AF_BLUETOOTH;
addr.rc_channel = 1;
@@ -712,7 +743,7 @@ altos_bt_open(struct altos_bt_device *device)
(struct sockaddr *)&addr,
sizeof(addr));
if (status < 0) {
- perror("connect");
+ altos_set_last_posix_error();
goto no_link;
}
sleep(1);
@@ -730,7 +761,6 @@ no_sock:
no_file:
return NULL;
}
-#endif /* HAS_BLUETOOTH */
#endif
@@ -844,6 +874,48 @@ altos_list_finish(struct altos_list *list)
free(list);
}
+struct altos_bt_list {
+ int sock;
+ int dev_id;
+ int rsp;
+ int num_rsp;
+};
+
+#define INQUIRY_MAX_RSP 255
+
+struct altos_bt_list *
+altos_bt_list_start(int inquiry_time)
+{
+ return NULL;
+}
+
+int
+altos_bt_list_next(struct altos_bt_list *bt_list,
+ struct altos_bt_device *device)
+{
+ return 0;
+}
+
+void
+altos_bt_list_finish(struct altos_bt_list *bt_list)
+{
+}
+
+void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
+{
+ strncpy(device->name, name, sizeof (device->name));
+ device->name[sizeof(device->name)-1] = '\0';
+ strncpy(device->addr, addr, sizeof (device->addr));
+ device->addr[sizeof(device->addr)-1] = '\0';
+}
+
+struct altos_file *
+altos_bt_open(struct altos_bt_device *device)
+{
+ return NULL;
+}
+
#endif
@@ -872,6 +944,21 @@ struct altos_file {
OVERLAPPED ov_write;
};
+static void
+altos_set_last_windows_error(void)
+{
+ DWORD error = GetLastError();
+ TCHAR message[1024];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ error,
+ 0,
+ message,
+ sizeof (message) / sizeof (TCHAR),
+ NULL);
+ altos_set_last_error(error, message);
+}
+
PUBLIC struct altos_list *
altos_list_start(void)
{
@@ -882,7 +969,7 @@ altos_list_start(void)
list->dev_info = SetupDiGetClassDevs(NULL, "USB", NULL,
DIGCF_ALLCLASSES|DIGCF_PRESENT);
if (list->dev_info == INVALID_HANDLE_VALUE) {
- printf("SetupDiGetClassDevs failed %ld\n", GetLastError());
+ altos_set_last_windows_error();
free(list);
return NULL;
}
@@ -916,6 +1003,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
DICS_FLAG_GLOBAL, 0, DIREG_DEV,
KEY_READ);
if (dev_key == INVALID_HANDLE_VALUE) {
+ altos_set_last_windows_error();
printf("cannot open device registry key\n");
continue;
}
@@ -926,6 +1014,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
result = RegQueryValueEx(dev_key, "SymbolicName", NULL, NULL,
symbolic, &symbolic_len);
if (result != 0) {
+ altos_set_last_windows_error();
printf("cannot find SymbolicName value\n");
RegCloseKey(dev_key);
continue;
@@ -948,6 +1037,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
port, &port_len);
RegCloseKey(dev_key);
if (result != 0) {
+ altos_set_last_windows_error();
printf("failed to get PortName\n");
continue;
}
@@ -963,6 +1053,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
sizeof(friendlyname),
&friendlyname_len))
{
+ altos_set_last_windows_error();
printf("Failed to get friendlyname\n");
continue;
}
@@ -975,8 +1066,10 @@ altos_list_next(struct altos_list *list, struct altos_device *device)
return 1;
}
result = GetLastError();
- if (result != ERROR_NO_MORE_ITEMS)
+ if (result != ERROR_NO_MORE_ITEMS) {
+ altos_set_last_windows_error();
printf ("SetupDiEnumDeviceInfo failed error %d\n", (int) result);
+ }
return 0;
}
@@ -995,8 +1088,10 @@ altos_queue_read(struct altos_file *file)
return LIBALTOS_SUCCESS;
if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, &file->ov_read)) {
- if (GetLastError() != ERROR_IO_PENDING)
+ if (GetLastError() != ERROR_IO_PENDING) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
file->pend_read = TRUE;
} else {
file->pend_read = FALSE;
@@ -1021,8 +1116,10 @@ altos_wait_read(struct altos_file *file, int timeout)
ret = WaitForSingleObject(file->ov_read.hEvent, timeout);
switch (ret) {
case WAIT_OBJECT_0:
- if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE))
+ if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE)) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
file->pend_read = FALSE;
file->in_read = 0;
file->in_used = got;
@@ -1066,15 +1163,20 @@ altos_flush(struct altos_file *file)
while (used) {
if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) {
- if (GetLastError() != ERROR_IO_PENDING)
+ if (GetLastError() != ERROR_IO_PENDING) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE);
switch (ret) {
case WAIT_OBJECT_0:
- if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE))
+ if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) {
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
+ }
break;
default:
+ altos_set_last_windows_error();
return LIBALTOS_ERROR;
}
}
@@ -1102,6 +1204,7 @@ altos_open(struct altos_device *device)
0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (file->handle == INVALID_HANDLE_VALUE) {
+ altos_set_last_windows_error();
free(file);
return NULL;
}
@@ -1117,6 +1220,7 @@ altos_open(struct altos_device *device)
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(file->handle, &dcbSerialParams)) {
+ altos_set_last_windows_error();
CloseHandle(file->handle);
free(file);
return NULL;
@@ -1126,6 +1230,7 @@ altos_open(struct altos_device *device)
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(file->handle, &dcbSerialParams)) {
+ altos_set_last_windows_error();
CloseHandle(file->handle);
free(file);
return NULL;
@@ -1180,4 +1285,38 @@ altos_getchar(struct altos_file *file, int timeout)
return file->in_data[file->in_read++];
}
+struct altos_bt_list *
+altos_bt_list_start(int inquiry_time)
+{
+ return NULL;
+}
+
+int
+altos_bt_list_next(struct altos_bt_list *bt_list,
+ struct altos_bt_device *device)
+{
+ return 0;
+}
+
+void
+altos_bt_list_finish(struct altos_bt_list *bt_list)
+{
+ free(bt_list);
+}
+
+void
+altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
+{
+ strncpy(device->name, name, sizeof (device->name));
+ device->name[sizeof(device->name)-1] = '\0';
+ strncpy(device->addr, addr, sizeof (device->addr));
+ device->addr[sizeof(device->addr)-1] = '\0';
+}
+
+struct altos_file *
+altos_bt_open(struct altos_bt_device *device)
+{
+ return NULL;
+}
+
#endif
diff --git a/altosui/libaltos/libaltos.h b/altosui/libaltos/libaltos.h
index 363a84fd..f90fbb87 100644
--- a/altosui/libaltos/libaltos.h
+++ b/altosui/libaltos/libaltos.h
@@ -51,6 +51,11 @@ struct altos_bt_device {
//%mutable;
};
+struct altos_error {
+ int code;
+ char string[1024];
+};
+
#define LIBALTOS_SUCCESS 0
#define LIBALTOS_ERROR -1
#define LIBALTOS_TIMEOUT -2
@@ -62,6 +67,9 @@ altos_init(void);
PUBLIC void
altos_fini(void);
+PUBLIC void
+altos_get_last_error(struct altos_error *error);
+
PUBLIC struct altos_list *
altos_list_start(void);
@@ -93,9 +101,6 @@ altos_flush(struct altos_file *file);
PUBLIC int
altos_getchar(struct altos_file *file, int timeout);
-// #define HAS_BLUETOOTH 1
-#if HAS_BLUETOOTH
-
PUBLIC struct altos_bt_list *
altos_bt_list_start(int inquiry_time);
@@ -111,6 +116,4 @@ altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device);
PUBLIC struct altos_file *
altos_bt_open(struct altos_bt_device *device);
-#endif
-
#endif /* _LIBALTOS_H_ */