12 static struct vehicle_priv {
14 struct callback_list *cbl;
17 struct gps_data_t *gps;
27 static gboolean vehicle_gpsd_io(GIOChannel * iochan,
28 GIOCondition condition, gpointer t);
33 vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
36 struct vehicle_priv *priv = vehicle_last;
37 // If data->fix.speed is NAN, then the drawing gets jumpy.
38 if (isnan(data->fix.speed)) {
42 if (data->set & SPEED_SET) {
43 priv->speed = data->fix.speed * 3.6;
44 data->set &= ~SPEED_SET;
46 if (data->set & TRACK_SET) {
47 priv->direction = data->fix.track;
48 data->set &= ~TRACK_SET;
50 if (data->set & ALTITUDE_SET) {
51 priv->height = data->fix.altitude;
52 data->set &= ~ALTITUDE_SET;
54 if (data->set & SATELLITE_SET) {
55 priv->sats_used = data->satellites_used;
56 priv->sats = data->satellites;
57 data->set &= ~SATELLITE_SET;
59 if (data->set & STATUS_SET) {
60 priv->status = data->status;
61 data->set &= ~STATUS_SET;
63 if (data->set & PDOP_SET) {
64 dbg(0, "pdop : %g\n", data->pdop);
65 data->set &= ~PDOP_SET;
67 if (data->set & LATLON_SET) {
68 priv->geo.lat = data->fix.latitude;
69 priv->geo.lng = data->fix.longitude;
70 callback_list_call_0(priv->cbl);
71 data->set &= ~LATLON_SET;
76 vehicle_gpsd_open(struct vehicle_priv *priv)
78 char *source = g_strdup(priv->source);
79 char *colon = index(source + 7, ':');
82 priv->gps = gps_open(source + 7, colon + 1);
84 priv->gps = gps_open(source + 7, NULL);
88 gps_query(priv->gps, "w+x\n");
89 gps_set_raw_hook(priv->gps, vehicle_gpsd_callback);
90 priv->iochan = g_io_channel_unix_new(priv->gps->gps_fd);
92 g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP,
93 vehicle_gpsd_io, priv);
98 vehicle_gpsd_close(struct vehicle_priv *priv)
100 GError *error = NULL;
103 g_source_remove(priv->watch);
107 g_io_channel_shutdown(priv->iochan, 0, &error);
111 gps_close(priv->gps);
117 vehicle_gpsd_io(GIOChannel * iochan, GIOCondition condition, gpointer t)
119 struct vehicle_priv *priv = t;
121 dbg(1, "enter condition=%d\n", condition);
122 if (condition == G_IO_IN) {
133 vehicle_gpsd_destroy(struct vehicle_priv *priv)
135 vehicle_gpsd_close(priv);
137 g_free(priv->source);
142 vehicle_gpsd_position_attr_get(struct vehicle_priv *priv,
143 enum attr_type type, struct attr *attr)
146 case attr_position_height:
147 attr->u.numd = &priv->height;
149 case attr_position_speed:
150 attr->u.numd = &priv->speed;
152 case attr_position_direction:
153 attr->u.numd = &priv->direction;
155 case attr_position_sats:
156 attr->u.num = priv->sats;
158 case attr_position_sats_used:
159 attr->u.num = priv->sats_used;
161 case attr_position_coord_geo:
162 attr->u.coord_geo = &priv->geo;
171 struct vehicle_methods vehicle_gpsd_methods = {
172 vehicle_gpsd_destroy,
173 vehicle_gpsd_position_attr_get,
176 static struct vehicle_priv *
177 vehicle_gpsd_new_gpsd(struct vehicle_methods
178 *meth, struct callback_list
179 *cbl, struct attr **attrs)
181 struct vehicle_priv *ret;
185 source = attr_search(attrs, NULL, attr_source);
186 ret = g_new0(struct vehicle_priv, 1);
187 ret->source = g_strdup(source->u.str);
189 *meth = vehicle_gpsd_methods;
190 if (vehicle_gpsd_open(ret))
192 dbg(0, "Failed to open '%s'\n", ret->source);
193 vehicle_gpsd_destroy(ret);
201 plugin_register_vehicle_type("gpsd", vehicle_gpsd_new_gpsd);