13 static struct vehicle_priv {
15 struct callback_list *cbl;
18 struct gps_data_t *gps;
28 static gboolean vehicle_gpsd_io(GIOChannel * iochan,
29 GIOCondition condition, gpointer t);
34 vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
37 struct vehicle_priv *priv = vehicle_last;
38 // If data->fix.speed is NAN, then the drawing gets jumpy.
39 if (isnan(data->fix.speed)) {
43 if (data->set & SPEED_SET) {
44 priv->speed = data->fix.speed * 3.6;
45 data->set &= ~SPEED_SET;
47 if (data->set & TRACK_SET) {
48 priv->direction = data->fix.track;
49 data->set &= ~TRACK_SET;
51 if (data->set & ALTITUDE_SET) {
52 priv->height = data->fix.altitude;
53 data->set &= ~ALTITUDE_SET;
55 if (data->set & SATELLITE_SET) {
56 priv->sats_used = data->satellites_used;
57 priv->sats = data->satellites;
58 data->set &= ~SATELLITE_SET;
60 if (data->set & STATUS_SET) {
61 priv->status = data->status;
62 data->set &= ~STATUS_SET;
64 if (data->set & PDOP_SET) {
65 dbg(0, "pdop : %g\n", data->pdop);
66 data->set &= ~PDOP_SET;
68 if (data->set & LATLON_SET) {
69 priv->geo.lat = data->fix.latitude;
70 priv->geo.lng = data->fix.longitude;
71 dbg(1,"lat=%f lng=%f\n", priv->geo.lat, priv->geo.lng);
72 callback_list_call_0(priv->cbl);
73 data->set &= ~LATLON_SET;
78 vehicle_gpsd_open(struct vehicle_priv *priv)
80 char *source = g_strdup(priv->source);
81 char *colon = index(source + 7, ':');
84 priv->gps = gps_open(source + 7, colon + 1);
86 priv->gps = gps_open(source + 7, NULL);
90 gps_query(priv->gps, "w+x\n");
91 gps_set_raw_hook(priv->gps, vehicle_gpsd_callback);
92 priv->iochan = g_io_channel_unix_new(priv->gps->gps_fd);
94 g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP,
95 vehicle_gpsd_io, priv);
100 vehicle_gpsd_close(struct vehicle_priv *priv)
102 GError *error = NULL;
105 g_source_remove(priv->watch);
109 g_io_channel_shutdown(priv->iochan, 0, &error);
113 gps_close(priv->gps);
119 vehicle_gpsd_io(GIOChannel * iochan, GIOCondition condition, gpointer t)
121 struct vehicle_priv *priv = t;
123 dbg(1, "enter condition=%d\n", condition);
124 if (condition == G_IO_IN) {
135 vehicle_gpsd_destroy(struct vehicle_priv *priv)
137 vehicle_gpsd_close(priv);
139 g_free(priv->source);
144 vehicle_gpsd_position_attr_get(struct vehicle_priv *priv,
145 enum attr_type type, struct attr *attr)
148 case attr_position_height:
149 attr->u.numd = &priv->height;
151 case attr_position_speed:
152 attr->u.numd = &priv->speed;
154 case attr_position_direction:
155 attr->u.numd = &priv->direction;
157 case attr_position_sats:
158 attr->u.num = priv->sats;
160 case attr_position_sats_used:
161 attr->u.num = priv->sats_used;
163 case attr_position_coord_geo:
164 attr->u.coord_geo = &priv->geo;
173 struct vehicle_methods vehicle_gpsd_methods = {
174 vehicle_gpsd_destroy,
175 vehicle_gpsd_position_attr_get,
178 static struct vehicle_priv *
179 vehicle_gpsd_new_gpsd(struct vehicle_methods
180 *meth, struct callback_list
181 *cbl, struct attr **attrs)
183 struct vehicle_priv *ret;
187 source = attr_search(attrs, NULL, attr_source);
188 ret = g_new0(struct vehicle_priv, 1);
189 ret->source = g_strdup(source->u.str);
191 *meth = vehicle_gpsd_methods;
192 if (vehicle_gpsd_open(ret))
194 dbg(0, "Failed to open '%s'\n", ret->source);
195 vehicle_gpsd_destroy(ret);
203 plugin_register_vehicle_type("gpsd", vehicle_gpsd_new_gpsd);