aoview: Add eeprom data fetching
authorKeith Packard <keithp@keithp.com>
Thu, 4 Jun 2009 00:07:34 +0000 (17:07 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 4 Jun 2009 00:07:34 +0000 (17:07 -0700)
Fetches the last flight data from a TM device connected via USB and writes
it to the flight log directory.

Signed-off-by: Keith Packard <keithp@keithp.com>
aoview/Makefile
aoview/aoview.glade
aoview/aoview.h
aoview/aoview_dev_dialog.c
aoview/aoview_eeprom.c [new file with mode: 0644]
aoview/aoview_file.c
aoview/aoview_log.c
aoview/aoview_main.c
aoview/aoview_monitor.c
aoview/aoview_serial.c
aoview/aoview_state.c

index ca636065a37c6e4c58c012c645855f6fc0bb3d3b..6bf789bb7e06e5dc9753140a8678a22638f1eab9 100644 (file)
@@ -18,7 +18,8 @@ SRC = \
        aoview_log.c \
        aoview_table.c \
        aoview_util.c \
-       aoview_file.c
+       aoview_file.c \
+       aoview_eeprom.c
 
 INC = \
        aoview.h
index eb7f108b7792016d47f26e2f81d8707c0689f17a..53297acae4df6d5e5ba5e3c607a5106c44ddb1d5 100644 (file)
                         </child>
                       </widget>
                     </child>
+                    <child>
+                      <widget class="GtkSeparatorMenuItem" id="seperator">
+                        <property name="visible">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="ao_savelog">
+                        <property name="label" translatable="yes">_Save EEPROM data</property>
+                        <property name="visible">True</property>
+                        <property name="use_underline">True</property>
+                        <property name="use_stock">False</property>
+                        <signal name="activate_item" handler="gtk_widget_show" object="device_connect_dialog" after="yes"/>
+                        <signal name="activate" handler="gtk_widget_show" object="device_connect_dialog"/>
+                        <child internal-child="image">
+                          <widget class="GtkImage" id="image5">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-save</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
                   </widget>
                 </child>
               </widget>
@@ -466,4 +487,35 @@ You should have received a copy of the GNU General Public License along with AoV
       </widget>
     </child>
   </widget>
+  <widget class="GtkMessageDialog" id="ao_save_done">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">EEPROM save complete</property>
+    <property name="type_hint">normal</property>
+    <property name="skip_taskbar_hint">True</property>
+    <property name="transient_for">aoview</property>
+    <property name="has_separator">False</property>
+    <property name="buttons">close</property>
+    <property name="text">Saving EEPROM data as</property>
+    <property name="secondary_text">&lt;filename&gt;</property>
+    <signal name="close" handler="gtk_widget_hide" object="ao_save_done"/>
+    <signal name="response" handler="gtk_widget_hide" object="ao_save_done"/>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox11">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area11">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>
index 7b5f0de5b7c5dd2ced0639032550ee4796721593..4eb4cd80b8a06d8ef267b0050c37e3f1e8209b24 100644 (file)
@@ -178,6 +178,9 @@ aoview_file_finish(struct aoview_file *file);
 gboolean
 aoview_file_start(struct aoview_file *file);
 
+const char *
+aoview_file_name(struct aoview_file *file);
+
 void
 aoview_file_set_serial(struct aoview_file *file, int serial);
 
@@ -199,4 +202,12 @@ aoview_file_destroy(struct aoview_file *file);
 void
 aoview_file_init(GladeXML *xml);
 
+/* aoview_eeprom.c */
+
+gboolean
+aoview_eeprom_save(const char *device);
+
+void
+aoview_eeprom_init(GladeXML *xml);
+
 #endif /* _AOVIEW_H_ */
index 530187c11369329912f12e4923520a199b4811eb..3f92085cfd5f0bdc4ccab3d62007c81b31456abe 100644 (file)
@@ -62,6 +62,8 @@ aoview_dev_open_failed(char *name)
        gtk_widget_hide(GTK_WIDGET(dev_open_fail_dialog));
 }
 
+gboolean       dialog_save_log;
+
 static void
 aoview_dev_selected(GtkTreeModel *model,
                    GtkTreePath *path,
@@ -72,8 +74,14 @@ aoview_dev_selected(GtkTreeModel *model,
        gtk_tree_model_get(model, iter,
                           2, &string,
                           -1);
-       if (!aoview_monitor_connect(string))
-               aoview_dev_open_failed(string);
+       if (dialog_save_log) {
+               dialog_save_log = FALSE;
+               if (!aoview_eeprom_save(string))
+                       aoview_dev_open_failed(string);
+       } else {
+               if (!aoview_monitor_connect(string))
+                       aoview_dev_open_failed(string);
+       }
 }
 
 static GtkWidget       *dialog;
@@ -90,7 +98,6 @@ aoview_dev_dialog_connect(GtkWidget *widget, gpointer data)
        gtk_tree_selection_selected_foreach(tree_selection,
                                            aoview_dev_selected,
                                            data);
-
        gtk_widget_hide(dialog);
 }
 
@@ -100,6 +107,13 @@ aoview_dev_disconnect(GtkWidget *widget)
        aoview_monitor_disconnect();
 }
 
+static void
+aoview_dev_savelog(GtkWidget *widget, gpointer data)
+{
+       dialog_save_log = TRUE;
+       gtk_widget_show(dialog);
+}
+
 #define _(a) a
 
 void
@@ -109,6 +123,7 @@ aoview_dev_dialog_init(GladeXML *xml)
        GtkWidget       *connect_button;
        GtkTreeSelection        *dev_selection;
        GtkWidget       *ao_disconnect;
+       GtkWidget       *ao_savelog;
 
        dialog = glade_xml_get_widget(xml, "device_connect_dialog");
        assert(dialog);
@@ -142,6 +157,12 @@ aoview_dev_dialog_init(GladeXML *xml)
                         G_CALLBACK(aoview_dev_disconnect),
                         ao_disconnect);
 
+       ao_savelog = glade_xml_get_widget(xml, "ao_savelog");
+       assert(ao_savelog);
+
+       g_signal_connect(G_OBJECT(ao_savelog), "activate",
+                        G_CALLBACK(aoview_dev_savelog),
+                        dialog);
        dev_open_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "dev_open_fail_dialog"));
        assert(dev_open_fail_dialog);
 }
diff --git a/aoview/aoview_eeprom.c b/aoview/aoview_eeprom.c
new file mode 100644 (file)
index 0000000..826afc4
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2009 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.
+ */
+
+#include "aoview.h"
+
+#define EEPROM_LEN     1024
+
+static struct aoview_file      *eeprom_file;
+static char                    eeprom_line[EEPROM_LEN + 1];
+static int                     eeprom_pos;
+static GtkMessageDialog                *eeprom_save_done;
+static GtkWidget               *eeprom_save_close;
+static gboolean                        eeprom_save_shown;
+
+static void
+aoview_eeprom_disconnect(struct aoview_serial *serial)
+{
+       aoview_file_finish(eeprom_file);
+}
+
+static void
+aoview_eeprom_done(struct aoview_serial *serial)
+{
+       gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
+                            "EEPROM data saved");
+       gtk_message_dialog_set_markup(eeprom_save_done,
+                                     "<b>EEPROM data saved as</b>");
+       if (!eeprom_save_shown)
+               gtk_widget_show(GTK_WIDGET(eeprom_save_done));
+       eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
+       if (eeprom_save_close)
+               gtk_widget_set_sensitive(eeprom_save_close, TRUE);
+       aoview_eeprom_disconnect(serial);
+}
+
+static gboolean
+aoview_eeprom_parse(struct aoview_serial *serial,
+                   char *line)
+{
+       char            cmd;
+       int             tick;
+       int             a;
+       int             b;
+       int             serial_number;
+       const char      *name;
+       char            *utf8_name;
+
+       if (!strcmp(line, "end")) {
+               aoview_eeprom_done(serial);
+               return FALSE;
+       }
+       if (sscanf(line, "serial-number %u", &serial_number) == 1) {
+               aoview_file_set_serial(eeprom_file, serial_number);
+       } else if (sscanf(line, "%c %x %x %x", &cmd, &tick, &a, &b) == 4) {
+               aoview_file_printf(eeprom_file, "%s\n", line);
+               if (cmd == 'S' && a == 8) {
+                       aoview_eeprom_done(serial);
+                       return FALSE;
+               }
+
+               if (!eeprom_save_shown)
+               {
+                       name = aoview_file_name(eeprom_file);
+                       if (name) {
+                               utf8_name = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
+                               if (!utf8_name)
+                                       utf8_name = (char *) name;
+                               gtk_widget_set_sensitive(eeprom_save_close, FALSE);
+                               gtk_window_set_title(GTK_WINDOW(eeprom_save_done),
+                                                    "Saving EEPROM data");
+                               gtk_message_dialog_set_markup(eeprom_save_done,
+                                                             "<b>Saving EEPROM data as</b>");
+                               gtk_message_dialog_format_secondary_text(eeprom_save_done, "%s",
+                                                                        utf8_name);
+                               if (utf8_name != name)
+                                       g_free(utf8_name);
+                               gtk_container_check_resize(GTK_CONTAINER(eeprom_save_done));
+                               gtk_widget_show(GTK_WIDGET(eeprom_save_done));
+                               eeprom_save_shown = TRUE;
+                               eeprom_save_close = gtk_window_get_default_widget(GTK_WINDOW(eeprom_save_done));
+                               if (eeprom_save_close)
+                                       gtk_widget_set_sensitive(eeprom_save_close, FALSE);
+                       }
+               }
+       }
+       return TRUE;
+}
+
+static void
+aoview_eeprom_callback(gpointer user_data,
+                      struct aoview_serial *serial,
+                      gint revents)
+{
+       int     c;
+
+       if (revents & (G_IO_HUP|G_IO_ERR)) {
+               aoview_eeprom_disconnect(serial);
+               return;
+       }
+       if (revents & G_IO_IN) {
+               for (;;) {
+                       c = aoview_serial_getc(serial);
+                       if (c == -1)
+                               break;
+                       if (c == '\r')
+                               continue;
+                       if (c == '\n') {
+                               eeprom_line[eeprom_pos] = '\0';
+                               if (eeprom_pos)
+                               if (!aoview_eeprom_parse(serial, eeprom_line))
+                                       break;
+                               eeprom_pos = 0;
+                       } else if (eeprom_pos < EEPROM_LEN)
+                               eeprom_line[eeprom_pos++] = c;
+               }
+       }
+}
+
+gboolean
+aoview_eeprom_save(const char *device)
+{
+       struct aoview_serial    *serial;
+
+       gtk_widget_hide(GTK_WIDGET(eeprom_save_done));
+       eeprom_save_shown = FALSE;
+       serial = aoview_serial_open(device);
+       if (!serial)
+               return FALSE;
+       aoview_serial_set_callback(serial, aoview_eeprom_callback, serial, NULL);
+       aoview_serial_printf(serial, "v\nl\n");
+       return TRUE;
+}
+
+void
+aoview_eeprom_init(GladeXML *xml)
+{
+       eeprom_file = aoview_file_new("eeprom");
+       assert(eeprom_file);
+
+       eeprom_save_done = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "ao_save_done"));
+       assert(eeprom_save_done);
+
+}
index d86d5878f8b4ce7a1ce51ad5c72a2c438a63fe99..4a8841d6f4d47aa162d245c363ecfe64febe0a78 100644 (file)
@@ -68,6 +68,12 @@ aoview_file_finish(struct aoview_file *file)
        file->failed = 0;
 }
 
+const char *
+aoview_file_name(struct aoview_file *file)
+{
+       return file->name;
+}
+
 static GtkMessageDialog *file_fail_dialog;
 
 static void
index 2f2b95608fcd86f2b7c6d67d8009226936e4ba0f..1b89c28cd602b1253330f91bc74dc964dbee00e6 100644 (file)
@@ -59,7 +59,7 @@ aoview_log_init(GladeXML *xml)
 {
        GtkWidget       *log_new;
 
-       aoview_log = aoview_file_new("log");
+       aoview_log = aoview_file_new("telem");
        assert(aoview_log);
 
        log_new = glade_xml_get_widget(xml, "log_new");
index 8d000993338ec269af2540802e42515c5ff41b97..45907519d32d2553be5f4587ea074d6e6b6dfc44 100644 (file)
@@ -87,6 +87,8 @@ int main(int argc, char **argv)
 
        aoview_table_init(xml);
 
+       aoview_eeprom_init(xml);
+
        gtk_main();
 
        return 0;
index 0fd535f210584732f27d6254660dd41cd154cec4..e2ba75bab0f8f9d92e7a3c47fe43ad697aca3c6b 100644 (file)
@@ -88,8 +88,7 @@ aoview_monitor_parse(char *line)
                return;
        aoview_parse_string(state.callsign, sizeof (state.callsign), words[1]);
        aoview_parse_int(&state.serial, words[3]);
-       if (!aoview_log_get_serial())
-               aoview_log_set_serial(state.serial);
+       aoview_log_set_serial(state.serial);
 
        aoview_parse_int(&state.rssi, words[5]);
        aoview_parse_string(state.state, sizeof (state.state), words[9]);
index 1721a28671d8a01ab7cd2d66cbd98be719cdf85b..1d8fefcedc94cb9ee1df1135bbb57cef005cbf56 100644 (file)
@@ -259,6 +259,7 @@ aoview_serial_close(struct aoview_serial *serial)
        g_source_remove_poll(&serial->source, &serial->poll_fd);
        g_source_destroy(&serial->source);
        g_source_unref(&serial->source);
+       free(serial);
 }
 
 void
index 02ae0307c249ac9cb7c736de7ff649a1edf576e6..356828c65a3b0bc1e58e063974e11bbe0e6a10a8 100644 (file)
@@ -56,15 +56,20 @@ aoview_great_circle (double start_lat, double start_lon,
 }
 
 static void
-aoview_state_add_deg(char *label, double deg)
+aoview_state_add_deg(char *label, double deg, char pos, char neg)
 {
        double  int_part;
        double  min;
+       char    sign = pos;
 
+       if (deg < 0) {
+               deg = -deg;
+               sign = neg;
+       }
        int_part = floor (deg);
        min = (deg - int_part) * 60.0;
-       aoview_table_add_row(label, "%d°%lf'",
-                            (int) int_part, min);
+       aoview_table_add_row(label, "%d°%lf'%c",
+                            (int) int_part, min, sign);
 
 }
 
@@ -139,8 +144,8 @@ aoview_state_notify(struct aostate *state)
        aoview_table_add_row("Pad altitude", "%dm", aoview_pres_to_altitude(state->ground_pres));
        aoview_table_add_row("Satellites", "%d", state->nsat);
        if (state->locked) {
-               aoview_state_add_deg("Latitude", state->lat);
-               aoview_state_add_deg("Longitude", state->lon);
+               aoview_state_add_deg("Latitude", state->lat, 'N', 'S');
+               aoview_state_add_deg("Longitude", state->lon, 'E', 'W');
                aoview_table_add_row("GPS alt", "%d", state->alt);
                aoview_table_add_row("GPS time", "%02d:%02d:%02d",
                                     state->gps_time.hour,
@@ -154,8 +159,8 @@ aoview_state_notify(struct aostate *state)
                aoview_table_add_row("GPS", "unlocked");
        }
        if (npad_gps) {
-               aoview_state_add_deg("Pad latitude", pad_lat);
-               aoview_state_add_deg("Pad longitude", pad_lon);
+               aoview_state_add_deg("Pad latitude", pad_lat, 'N', 'S');
+               aoview_state_add_deg("Pad longitude", pad_lon, 'E', 'W');
                aoview_table_add_row("Pad GPS alt", "%gm", pad_alt);
        }
        aoview_table_finish();