]> ToastFreeware Gitweb - gregoa/zavai.git/blobdiff - src/gps.vala
Removed useless select call
[gregoa/zavai.git] / src / gps.vala
index 0336cb3e3d3a54bfbdd20f2b9abf44a9fbb6b8b0..64037ce3a849c56b54d56bef02c47a19ce2d002a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * gps - gps resource for zavai
  *
- * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
+ * Copyright (C) 2009--2010  Enrico Zini <enrico@enricozini.org>
  *
  * 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
@@ -24,183 +24,138 @@ namespace zavai {
 namespace gps {
 
 // For a list of dbus services, look in /etc/dbus-1/system.d/
-public class GPS: zavai.Service
+public class GPS: zavai.ScriptService
 {
-       public dynamic DBus.Object usage;
-       public dynamic DBus.Object device;
-
-       public GPS()
-       {
-               Object(name: "gps");
-
-               // see mdbus -s org.freesmartphone.ousaged /org/freesmartphone/Usage
-               usage = zavai.registry.sbus.get_object(
-                       "org.freesmartphone.ousaged",
-                       "/org/freesmartphone/Usage",
-                       "org.freesmartphone.Usage");
-
-               device = zavai.registry.sbus.get_object(
-                       "org.freesmartphone.ogpsd", 
-                       "/org/freedesktop/Gypsy",
-                       "org.freedesktop.Gypsy.Device");
-       }
-
-    public void power_cycle(bool aggressive)
+    protected libgps.data_t data;
+    protected IOChannel gpsfd = null;
+    protected uint gpsfd_watch = 0;
+
+    protected int old_fix_status = libgps.STATUS_NO_FIX;
+    protected uint old_time = 0;
+    protected double old_lat = 1000;
+    protected double old_lon = 1000;
+
+    public signal void fix_status_changed(int status);
+    public signal void time_changed(uint time);
+    public signal void pos_changed();
+
+    public GPS()
     {
-        // "Have you tried turning it off and on again?"
-               try {
-            usage.SetResourcePolicy("GPS", "disabled");
-               } catch (GLib.Error e) {
-                       zavai.log.error(e.message);
-               }
-        Thread.usleep(500000);
-        if (aggressive)
-            // Sometimes the GPS crashes because its state contains something
-            // that makes it crash, so we need to remove the saved state or it
-            // crashes again quite soon
-            FileUtils.unlink("/var/lib/freesmartphone/ogpsd.pickle");
-               try {
-            usage.SetResourcePolicy("GPS", "auto");
-               } catch (GLib.Error e) {
-                       zavai.log.error(e.message);
-               }
+        Object(name: "gps");
+        data = libgps.data_t();
+        started = script_status();
     }
 
-       /// Request GPS resource
-       public override void start()
-       {
-               if (started) return;
-               bool done = false;
-/*             
-               try {
-                       // First try with FSO
-                       usage.RequestResource("GPS");
-                       done = true;
-               } catch (GLib.Error e) {
-                       zavai.log.error("Requesting resource GPS: " + e.message);
-               }
-               if (!done)
-               {
-                       try {
-                               // Then make it work for fil
-                               // TODO: switch fil to om
-                               zavai.app.run_script("om-device start gps");
-                               done = true;
-                       } catch (Error e) {
-                               zavai.log.error("Running om-device start gps: " + e.message);
-                       }
-               }
-*/
-               if (!done)
-               {
-                       try {
-                               // Then run our own script
-                               zavai.app.run_script(zavai.config.homedir + "/gps start");
-                               done = true;
-                       } catch (Error e) {
-                               zavai.log.error("Running " + zavai.config.homedir + "/gps on: " + e.message);
-                       }
-               }
-               if (done)
-                       zavai.log.info("GPS turned on");
-               else
-                       zavai.log.error("Could not turn on GPS");
-               base.start();
-       }
-
-       // Release usage of GPS
-       public override void stop()
-       {
-               if (!started) return;
-               bool done = false;
-/*
-               try {
-                       usage.ReleaseResource("GPS");
-                       done = true;
-               } catch (GLib.Error e) {
-                       zavai.log.error("Releasing resource GPS: " + e.message);
-               }
-               if (!done)
-               {
-                       try {
-                               zavai.app.run_script("om-device stop gps");
-                               done = true;
-                       } catch (Error e) {
-                               zavai.log.error("Running device stop gps: " + e.message);
-                       }
-               }
-*/
-               if (!done)
-               {
-                       try {
-                               zavai.app.run_script(zavai.config.homedir + "/gps stop");
-                               done = true;
-                       } catch (Error e) {
-                               zavai.log.error("Running device stop gps: " + e.message);
-                       }
-               }
-               if (done)
-                       zavai.log.info("GPS turned off");
-               else
-                       zavai.log.error("Could not turn off GPS");
-               base.stop();
-       }
-}
+    public int fix_status() { return old_fix_status; }
+    public double time() { return old_time; }
+    public weak libgps.data_t info() { return data; }
 
-public class Position : zavai.Service
-{
-       dynamic DBus.Object position;
-
-       public signal void position_changed(int fields, int tstamp, double lat, double lon, double alt);
-
-       public Position()
-       {
-               Object(name: "gps.position");
-               position = zavai.registry.sbus.get_object(
-                       "org.freesmartphone.ogpsd",
-                       "/org/freedesktop/Gypsy",
-                       "org.freedesktop.Gypsy.Position");
-       }
-
-       public void on_position_changed(dynamic DBus.Object pos, int fields, int tstamp, double lat, double lon, double alt)
-       {
-               zavai.log.info("gps position: position changed");
-               position_changed(fields, tstamp, lat, lon, alt);
-       }
-
-       public override void start()
-       {
-               if (started) return;
-               zavai.log.info("Starting GPS position tracking");
-               gps.request("gps.position");
-               position.PositionChanged += on_position_changed;
-               base.start();
-       }
-
-       public override void stop()
-       {
-               if (!started) return;
-               zavai.log.info("Stopping GPS position tracking");
-               position.PositionChanged -= on_position_changed;
-               gps.release("gps.position");
-               base.stop();
-       }
+    protected bool on_input_data(IOChannel source, IOCondition condition)
+    {
+        int res = libgps.poll(ref data);
+        if (res != 0)
+            zavai.log.error(libgps.errstr(res));
+
+        if (data.status != old_fix_status)
+        {
+            fix_status_changed(data.status);
+            old_fix_status = data.status;
+        }
+
+        uint cur_time = (uint)data.fix.time;
+        if (data.status != libgps.STATUS_NO_FIX && old_time != cur_time)
+        {
+            time_changed(cur_time);
+            old_time = cur_time;
+        }
+
+        double lat = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.latitude);
+        double lon = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.longitude);
+        if (lat != old_lat || lon != old_lon)
+            pos_changed();
+
+        /*
+        stderr.printf("GPSMSG %d %d\n", (int)data.set, data.status);
+        stderr.printf("SATUSED %d\n", data.satellites_used);
+        stderr.printf("SWT %f\n", data.skyview_time);
+        stderr.printf("SATVIS %d\n", data.satellites_visible);
+        for (int i = 0; i < data.satellites_visible; ++i)
+        {
+            stderr.printf("PRN %d ELE %d AZI %d SS %f\n",
+                data.PRN[i], data.elevation[i], data.azimuth[i], data.ss[i]);
+        }
+        */
+        return true;
+    }
+
+    /// Request GPS resource
+    public override void start()
+    {
+        if (started) return;
+
+        if (!script_start()) return;
+
+        zavai.log.info("Connecting to gpsd at " + config.gpsd_host + ":" + config.gpsd_port);
+        int res = libgps.open_r(config.gpsd_host, config.gpsd_port, ref data);
+        if (res != 0)
+        {
+            zavai.log.error(libgps.errstr(res));
+            return;
+        }
+
+        res = libgps.stream(ref data, libgps.WATCH_ENABLE, null);
+        if (res != 0)
+        {
+            zavai.log.error(libgps.errstr(res));
+            return;
+        }
+
+        //res = libgps.send(ref data, "?SKY;");
+        //res = libgps.send(ref data, "?WATCH;");
+        //if (res != 0) zavai.log.error(libgps.errstr(res));
+
+        gpsfd = new IOChannel.unix_new(data.gps_fd);
+        try {
+            gpsfd.set_encoding(null);
+        } catch (Error e) {
+            zavai.log.error("Setting encoding to null on gpsd io channel: " + e.message);
+        }
+        //gpsfd.set_buffered(false);
+        gpsfd_watch = gpsfd.add_watch(IOCondition.IN, on_input_data);
+
+        zavai.log.info("GPS turned on");
+        base.start();
+    }
+
+    // Release usage of GPS
+    public override void stop()
+    {
+        if (!started) return;
+
+        Source.remove(gpsfd_watch);
+
+        int res = libgps.close(ref data);
+        if (res != 0)
+            zavai.log.error(libgps.errstr(res));
+
+        script_stop();
+
+        if (old_fix_status != libgps.STATUS_NO_FIX)
+        {
+            old_fix_status = libgps.STATUS_NO_FIX;
+            fix_status_changed(old_fix_status);
+        }
+
+        if (old_time != 0)
+        {
+            old_time = 0;
+            time_changed(old_time);
+        }
+
+        base.stop();
+    }
 }
 
-// #    def wait_for_fix(self, callback):
-// #        status = self.gps.GetFixStatus()
-// #        if status in [2, 3]:
-// #            zavai.info("We already have a fix, good.")
-// #            callback()
-// #            return True
-// #        else:
-// #            zavai.info("Waiting for a fix...")
-// #            self.waiting_for_fix = callback
-// #            self.bus.add_signal_receiver(
-// #                self.on_fix_status_changed, 'FixStatusChanged', 'org.freedesktop.Gypsy.Device',
-// #                'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
-// #            return False
-// #
 // #    def start_recording(self):
 // #        if self.gps_monitor:
 // #            self.gps_monitor.stop()
@@ -230,179 +185,59 @@ public class Position : zavai.Service
 // Write GPX track and waypoint files
 public class GPX : Service
 {
-       public bool tracking {
-               get { return trk != null; }
-               set {}
-       }
-       public signal void tracking_changed(bool tracking);
-
-       FileStream trk = null;
-       FileStream wpt = null;
-       int wpt_seq = 1;
-       bool last_valid = false;
-       int last_fields;
-       time_t last_tstamp;
-       double last_lat;
-       double last_lon;
-       double last_alt;
-
-       public GPX()
-       {
-               Object(name: "gps.gpx");
-       }
-
-       public override void start()
-       {       
-               if (!started)
-               {
-                       log.info("Starting GPX trace subsystem");
-                       position.request("gps.gpx");
-                       position.position_changed += on_position_changed;
-                       base.start();
-               }
-       }
-
-       public override void stop()
-       {
-               if (started)
-               {
-                       log.info("Stopping GPX trace subsystem");
-                       position.release("gps.gpx");
-                       position.position_changed -= on_position_changed;
-                       stop_track();
-                       base.stop();
-               }
-       }
-
-       public void on_position_changed(Position pos, int fields, int tstamp, double lat, double lon, double alt)
-       {
-               last_fields = fields;
-               last_tstamp = tstamp;
-               last_lat = lat;
-               last_lon = lon;
-               last_alt = alt;
-               last_valid = true;
-               trackpoint();
-       }
-
-       public void start_track(time_t tstamp = 0, string? basename = null)
-       {
-               string fname;
-               if (basename != null)
-                       fname = basename;
-               else
-               {
-                       time_t now = tstamp == 0 ? time_t() : tstamp;
-
-                       // Compute basename for output files
-                       var t = Time.local(now);
-                       char[] res = new char[25];
-                       t.strftime(res, "%Y-%m-%d-%H-%M-%S");
-                       fname = zavai.config.homedir + "/" + (string)res;
-               }
-               trk = FileStream.open(fname + "-trk.gpx", "wt");
-               trk.puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-               trk.puts(" <gpx");
-               trk.puts("     version=\"1.0\"");
-               trk.printf("     creator=\"zavai %s\"\n", zavai.config.version);
-               trk.puts("     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
-               trk.puts("     xmlns=\"http://www.topografix.com/GPX/1/0\"");
-               trk.puts("     xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">");
-               trk.puts("   <trk>");
-               trk.puts("     <trkseg>");
-               wpt = FileStream.open(fname + "-wpt.gpx", "wt");
-               wpt.puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-               wpt.puts(" <gpx");
-               wpt.puts("     version=\"1.0\"");
-               wpt.printf("     creator=\"zavai %s\"", zavai.config.version);
-               wpt.puts("     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
-               wpt.puts("     xmlns=\"http://www.topografix.com/GPX/1/0\"");
-               wpt.puts("     xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">");
-               wpt_seq = 1;
-               tracking_changed(true);
-       }
-       public void stop_track()
-       {
-               if (trk != null)
-               {
-                       trk.puts("</trkseg></trk></gpx>");
-                       trk.flush();
-                       trk = null;
-               }
-               if (wpt != null)
-               {
-                       wpt.puts("</gpx>");
-                       wpt.flush();
-                       wpt = null;
-               }
-               last_valid = false;
-               tracking_changed(false);
-       }
-
-       // Mark a track point
-       public void trackpoint()
-       {
-               if (!last_valid) return;
-               if (trk == null)
-                       start_track(last_tstamp);
-
-               trk.printf("<trkpt lat=\"%f\" lon=\"%f\">\n", last_lat, last_lon);
-               var t = Time.local(last_tstamp);
-               char[] ts = new char[25];
-               t.strftime(ts, "%Y-%m-%dT%H:%M:%SZ");
-               trk.printf("  <time>%s</time>\n", (string)ts);
-               trk.printf("  <ele>%f</ele>\n", last_alt);
-               // if course is not None: print >>self.trk, "    <course>%f</course>" % course
-               // if speed is not None: print >>self.trk, "    <speed>%f</speed>" % speed
-               // if fix is not None: print >>self.trk, "    <fix>%f</fix>" % fix
-               // if hdop is not None: print >>self.trk, "    <hdop>%f</hdop>" % hdop
-               trk.puts("</trkpt>");
-       }
-
-       // Mark a waypoint
-       public void waypoint(string? name = null)
-       {
-               if (!last_valid) return;
-               if (wpt == null)
-                       start_track(last_tstamp);
-
-               string wptname;
-               if (name == null)
-               {
-                       wptname = "wpt_%d".printf(wpt_seq);
-                       wpt_seq += 1;
-               } else {
-                       wptname = name;
-               }
-
-               wpt.printf("<wpt lat=\"%f\" lon=\"%f\">\n", last_lat, last_lon);
-               wpt.printf("  <name>%s</name>\n", wptname);
-               var t = Time.local(last_tstamp);
-               char[] ts = new char[25];
-               t.strftime(ts, "%Y-%m-%dT%H:%M:%SZ");
-               wpt.printf("  <time>%s</time>\n", (string)ts);
-               wpt.printf("  <ele>%f</ele>\n", last_alt);
-               wpt.puts("</wpt>");
-       }
+    protected uint wpt_seq = 0;
+    protected zavai.log.Log log = null;
+
+    public GPX()
+    {
+        Object(name: "gps.gpx");
+    }
+
+    public override void start()
+    {
+        if (!started)
+        {
+            log = zavai.log.log.start("track", "GPS track");
+            base.start();
+        }
+    }
+
+    public override void stop()
+    {
+        if (started)
+        {
+            zavai.log.log.end(log);
+            log = null;
+            base.stop();
+        }
+    }
+
+    // Mark a waypoint
+    public void waypoint(string? name = null)
+    {
+        if (log == null) return;
+
+        string wptname;
+        if (name == null)
+        {
+            wptname = "wpt_%u".printf(wpt_seq);
+            wpt_seq += 1;
+        } else {
+            wptname = name;
+        }
+
+        log.add(wptname);
+    }
 }
 
 public zavai.gps.GPS gps = null;
-public zavai.gps.Position position = null;
 public zavai.gps.GPX gpx = null;
 
 public void init()
 {
-       gps = new GPS();
-       position = new Position();
-       gpx = new GPX();
+    gps = new GPS();
+    gpx = new GPX();
 
-       zavai.registry.register_service(gps);
-       zavai.registry.register_service(position);
-       zavai.registry.register_service(gpx);
 }
 
 }