32 |
#include <errno.h> |
#include <errno.h> |
33 |
#endif |
#endif |
34 |
|
|
35 |
|
static void gps_unregister_all(appdata_t *appdata); |
36 |
|
|
37 |
#ifndef ENABLE_LIBLOCATION |
#ifndef ENABLE_LIBLOCATION |
38 |
|
|
39 |
/* maybe user configurable later on ... */ |
/* maybe user configurable later on ... */ |
99 |
return retval; |
return retval; |
100 |
} |
} |
101 |
|
|
102 |
float gps_get_epe(appdata_t *appdata) { |
float gps_get_eph(appdata_t *appdata) { |
103 |
float retval = NAN; |
float retval = NAN; |
104 |
|
|
105 |
g_mutex_lock(appdata->gps_state->mutex); |
g_mutex_lock(appdata->gps_state->mutex); |
116 |
#ifdef USE_MAEMO |
#ifdef USE_MAEMO |
117 |
char errstr[256] = ""; |
char errstr[256] = ""; |
118 |
|
|
119 |
|
if(!gps_state) { |
120 |
|
printf("No gps state\n"); |
121 |
|
return -1; |
122 |
|
} |
123 |
|
|
124 |
/* We need to start gpsd (via gpsbt) first. */ |
/* We need to start gpsd (via gpsbt) first. */ |
125 |
memset(&gps_state->context, 0, sizeof(gpsbt_t)); |
memset(&gps_state->context, 0, sizeof(gpsbt_t)); |
126 |
errno = 0; |
errno = 0; |
127 |
|
|
128 |
if(gpsbt_start(NULL, 0, 0, 0, errstr, sizeof(errstr), |
if(gpsbt_start(NULL, 0, 0, 0, errstr, sizeof(errstr), |
129 |
0, &gps_state->context) < 0) { |
0, &gps_state->context) < 0) { |
130 |
printf("Error connecting to GPS receiver: (%d) %s (%s)\n", |
printf("gps: Error connecting to GPS receiver: (%d) %s (%s)\n", |
131 |
errno, strerror(errno), errstr); |
errno, strerror(errno), errstr); |
132 |
} |
} |
133 |
#endif |
#endif |
141 |
while(retries && |
while(retries && |
142 |
(GNOME_VFS_OK != (vfs_result = gnome_vfs_inet_connection_create( |
(GNOME_VFS_OK != (vfs_result = gnome_vfs_inet_connection_create( |
143 |
&gps_state->iconn, GPSD_HOST, GPSD_PORT, NULL)))) { |
&gps_state->iconn, GPSD_HOST, GPSD_PORT, NULL)))) { |
144 |
printf("Error creating connection to GPSD, retrying ...\n"); |
printf("gps: Error creating connection to GPSD, retrying ...\n"); |
145 |
|
|
146 |
retries--; |
retries--; |
147 |
sleep(1); |
sleep(1); |
148 |
} |
} |
149 |
|
|
150 |
if(!retries) { |
if(!retries) { |
151 |
printf("Finally failed ...\n"); |
printf("gps: Finally failed ...\n"); |
152 |
return -1; |
return -1; |
153 |
} |
} |
154 |
|
|
155 |
retries = 5; |
retries = 5; |
156 |
while(retries && ((gps_state->socket = |
while(retries && ((gps_state->socket = |
157 |
gnome_vfs_inet_connection_to_socket(gps_state->iconn)) == NULL)) { |
gnome_vfs_inet_connection_to_socket(gps_state->iconn)) == NULL)) { |
158 |
printf("Error creating connecting GPSD socket, retrying ...\n"); |
printf("gps: Error creating connecting GPSD socket, retrying ...\n"); |
159 |
|
|
160 |
retries--; |
retries--; |
161 |
sleep(1); |
sleep(1); |
162 |
} |
} |
163 |
|
|
164 |
if(!retries) { |
if(!retries) { |
165 |
printf("Finally failed ...\n"); |
printf("gps: Finally failed ...\n"); |
166 |
return -1; |
return -1; |
167 |
} |
} |
168 |
|
|
169 |
GTimeVal timeout = { 10, 0 }; |
GTimeVal timeout = { 10, 0 }; |
170 |
if(GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_set_timeout( |
if(GNOME_VFS_OK != (vfs_result = gnome_vfs_socket_set_timeout( |
171 |
gps_state->socket, &timeout, NULL))) { |
gps_state->socket, &timeout, NULL))) { |
172 |
printf("Error setting GPSD timeout\n"); |
printf("gps: Error setting GPSD timeout\n"); |
173 |
return -1; |
return -1; |
174 |
} |
} |
175 |
|
|
176 |
printf("GPSD connected ...\n"); |
printf("gps: GPSD connected ...\n"); |
177 |
|
|
178 |
return 0; |
return 0; |
179 |
} |
} |
182 |
fixp->mode = MODE_NOT_SEEN; |
fixp->mode = MODE_NOT_SEEN; |
183 |
fixp->pos.lat = fixp->pos.lon = NAN; |
fixp->pos.lat = fixp->pos.lon = NAN; |
184 |
fixp->track = NAN; |
fixp->track = NAN; |
|
fixp->speed = NAN; |
|
|
fixp->climb = NAN; |
|
|
fixp->altitude = NAN; |
|
|
fixp->ept = NAN; |
|
185 |
fixp->eph = NAN; |
fixp->eph = NAN; |
|
fixp->epv = NAN; |
|
|
fixp->epd = NAN; |
|
|
fixp->eps = NAN; |
|
|
fixp->epc = NAN; |
|
186 |
} |
} |
187 |
|
|
188 |
/* unpack a daemon response into a status structure */ |
/* unpack a daemon response into a status structure */ |
198 |
else *tp = '\0'; |
else *tp = '\0'; |
199 |
|
|
200 |
switch (*sp) { |
switch (*sp) { |
201 |
case 'A': |
/* A - altitude is not supported */ |
|
if (sp[2] == '?') { |
|
|
gpsdata->fix.altitude = NAN; |
|
|
} else { |
|
|
(void)sscanf(sp, "A=%lf", &gpsdata->fix.altitude); |
|
|
gpsdata->set |= ALTITUDE_SET; |
|
|
} |
|
|
break; |
|
202 |
/* B - baudrate isn't supported by gpxview */ |
/* B - baudrate isn't supported by gpxview */ |
203 |
/* C - cycle isn't supported by gpxview */ |
/* C - cycle isn't supported by gpxview */ |
204 |
/* D - utc time isn't supported by gpxview */ |
/* D - utc time isn't supported by gpxview */ |
205 |
case 'E': |
case 'E': |
206 |
gpsdata->epe = gpsdata->fix.eph = gpsdata->fix.epv = NAN; |
gpsdata->fix.eph = NAN; |
207 |
/* epe should always be present if eph or epv is */ |
/* epe should always be present if eph or epv is */ |
208 |
if (sp[2] != '?') { |
if (sp[2] != '?') { |
209 |
char epe[20], eph[20], epv[20]; |
char epe[20], eph[20], epv[20]; |
210 |
(void)sscanf(sp, "E=%s %s %s", epe, eph, epv); |
(void)sscanf(sp, "E=%s %s %s", epe, eph, epv); |
211 |
#define DEFAULT(val) (val[0] == '?') ? NAN : g_ascii_strtod(val, NULL) |
#define DEFAULT(val) (val[0] == '?') ? NAN : g_ascii_strtod(val, NULL) |
|
gpsdata->epe = DEFAULT(epe); |
|
212 |
gpsdata->fix.eph = DEFAULT(eph); |
gpsdata->fix.eph = DEFAULT(eph); |
|
gpsdata->fix.epv = DEFAULT(epv); |
|
213 |
#undef DEFAULT |
#undef DEFAULT |
214 |
} |
} |
215 |
break; |
break; |
247 |
#define DEFAULT(val) (val[0] == '?') ? NAN : g_ascii_strtod(val, NULL) |
#define DEFAULT(val) (val[0] == '?') ? NAN : g_ascii_strtod(val, NULL) |
248 |
nf.pos.lat = DEFAULT(lat); |
nf.pos.lat = DEFAULT(lat); |
249 |
nf.pos.lon = DEFAULT(lon); |
nf.pos.lon = DEFAULT(lon); |
|
nf.ept = DEFAULT(ept); |
|
|
nf.altitude = DEFAULT(alt); |
|
250 |
nf.eph = DEFAULT(eph); |
nf.eph = DEFAULT(eph); |
|
nf.epv = DEFAULT(epv); |
|
251 |
nf.track = DEFAULT(track); |
nf.track = DEFAULT(track); |
|
nf.speed = DEFAULT(speed); |
|
|
nf.climb = DEFAULT(climb); |
|
|
nf.epd = DEFAULT(epd); |
|
|
nf.eps = DEFAULT(eps); |
|
|
nf.epc = DEFAULT(epc); |
|
252 |
#undef DEFAULT |
#undef DEFAULT |
253 |
if (st >= 15) |
if (st >= 15) |
254 |
nf.mode = (mode[0] == '?') ? MODE_NOT_SEEN : atoi(mode); |
nf.mode = (mode[0] == '?') ? MODE_NOT_SEEN : atoi(mode); |
255 |
else |
else |
256 |
nf.mode = (alt[0] == '?') ? MODE_2D : MODE_3D; |
nf.mode = (alt[0] == '?') ? MODE_2D : MODE_3D; |
|
if (alt[0] != '?') |
|
|
gpsdata->set |= ALTITUDE_SET | CLIMB_SET; |
|
257 |
if (isnan(nf.eph)==0) |
if (isnan(nf.eph)==0) |
258 |
gpsdata->set |= HERR_SET; |
gpsdata->set |= HERR_SET; |
|
if (isnan(nf.epv)==0) |
|
|
gpsdata->set |= VERR_SET; |
|
259 |
if (isnan(nf.track)==0) |
if (isnan(nf.track)==0) |
260 |
gpsdata->set |= TRACK_SET | SPEED_SET; |
gpsdata->set |= TRACK_SET; |
|
if (isnan(nf.eps)==0) |
|
|
gpsdata->set |= SPEEDERR_SET; |
|
|
if (isnan(nf.epc)==0) |
|
|
gpsdata->set |= CLIMBERR_SET; |
|
261 |
gpsdata->fix = nf; |
gpsdata->fix = nf; |
262 |
gpsdata->set |= TIME_SET|TIMERR_SET|LATLON_SET|MODE_SET; |
gpsdata->set |= LATLON_SET|MODE_SET; |
263 |
gpsdata->status = STATUS_FIX; |
gpsdata->status = STATUS_FIX; |
264 |
gpsdata->set |= STATUS_SET; |
gpsdata->set |= STATUS_SET; |
265 |
} |
} |
277 |
gpsdata->set |= LATLON_SET; |
gpsdata->set |= LATLON_SET; |
278 |
} |
} |
279 |
break; |
break; |
280 |
case 'Q': |
/* Q is not supported */ |
|
if (sp[2] == '?') { |
|
|
gpsdata->satellites_used = 0; |
|
|
gpsdata->pdop = 0; |
|
|
gpsdata->hdop = 0; |
|
|
gpsdata->vdop = 0; |
|
|
} else { |
|
|
(void)sscanf(sp, "Q=%d %lf %lf %lf %lf %lf", |
|
|
&gpsdata->satellites_used, |
|
|
&gpsdata->pdop, |
|
|
&gpsdata->hdop, |
|
|
&gpsdata->vdop, |
|
|
&gpsdata->tdop, |
|
|
&gpsdata->gdop); |
|
|
gpsdata->set |= HDOP_SET | VDOP_SET | PDOP_SET; |
|
|
} |
|
|
break; |
|
281 |
case 'S': |
case 'S': |
282 |
if (sp[2] == '?') { |
if (sp[2] == '?') { |
283 |
gpsdata->status = -1; |
gpsdata->status = -1; |
290 |
if (sp[2] == '?') { |
if (sp[2] == '?') { |
291 |
gpsdata->fix.track = NAN; |
gpsdata->fix.track = NAN; |
292 |
} else { |
} else { |
293 |
(void)sscanf(sp, "T=%lf", &gpsdata->fix.track); |
(void)sscanf(sp, "T=%f", &gpsdata->fix.track); |
294 |
gpsdata->set |= TRACK_SET; |
gpsdata->set |= TRACK_SET; |
295 |
} |
} |
296 |
break; |
break; |
297 |
case 'U': |
/* U - climb is not supported */ |
298 |
if (sp[2] == '?') { |
/* V - is not supported */ |
299 |
gpsdata->fix.climb = NAN; |
/* X - online is not supported */ |
|
} else { |
|
|
(void)sscanf(sp, "U=%lf", &gpsdata->fix.climb); |
|
|
gpsdata->set |= CLIMB_SET; |
|
|
} |
|
|
break; |
|
|
case 'V': |
|
|
if (sp[2] == '?') { |
|
|
gpsdata->fix.speed = NAN; |
|
|
} else { |
|
|
(void)sscanf(sp, "V=%lf", &gpsdata->fix.speed); |
|
|
/* V reply is in kt, fix.speed is in metres/sec */ |
|
|
gpsdata->fix.speed = gpsdata->fix.speed / MPS_TO_KNOTS; |
|
|
gpsdata->set |= SPEED_SET; |
|
|
} |
|
|
break; |
|
|
case 'X': |
|
|
if (sp[2] == '?') |
|
|
gpsdata->online = -1; |
|
|
else { |
|
|
(void)sscanf(sp, "X=%lf", &gpsdata->online); |
|
|
gpsdata->set |= ONLINE_SET; |
|
|
} |
|
|
break; |
|
300 |
case 'Y': |
case 'Y': |
301 |
if (sp[2] == '?') { |
if (sp[2] == '?') { |
302 |
gpsdata->satellites = 0; |
gpsdata->satellites = 0; |
312 |
for (j = 0; j < gpsdata->satellites; j++) { |
for (j = 0; j < gpsdata->satellites; j++) { |
313 |
PRN[j]=elevation[j]=azimuth[j]=ss[j]=used[j]=0; |
PRN[j]=elevation[j]=azimuth[j]=ss[j]=used[j]=0; |
314 |
} |
} |
315 |
// printf("sats = %d\n", gpsdata->satellites); |
// printf("gps: sats = %d\n", gpsdata->satellites); |
316 |
for (j = 0, gpsdata->satellites_used = 0; j < gpsdata->satellites; j++) { |
for (j = 0, gpsdata->satellites_used = 0; j < gpsdata->satellites; j++) { |
317 |
if ((sp != NULL) && ((sp = strchr(sp, ':')) != NULL)) { |
if ((sp != NULL) && ((sp = strchr(sp, ':')) != NULL)) { |
318 |
sp++; |
sp++; |
340 |
} |
} |
341 |
} |
} |
342 |
|
|
343 |
|
/* call one of the application provided gps callbacks */ |
344 |
|
static void do_app_cb(gpointer data, gpointer user_data) { |
345 |
|
appdata_t *appdata = (appdata_t*)user_data; |
346 |
|
gps_cb_t *cb = (gps_cb_t*)data; |
347 |
|
cb->cb(appdata->gps_state, cb->data); |
348 |
|
} |
349 |
|
|
350 |
|
/* walk though list of all application provided callbacks */ |
351 |
|
static gboolean gps_idle_cb(gpointer data) { |
352 |
|
appdata_t *appdata = (appdata_t*)data; |
353 |
|
// printf("gps: idle callback, calling app callbacks\n"); |
354 |
|
|
355 |
|
g_slist_foreach(appdata->gps_state->cb, do_app_cb, appdata); |
356 |
|
|
357 |
|
return FALSE; |
358 |
|
} |
359 |
|
|
360 |
gpointer gps_thread(gpointer data) { |
gpointer gps_thread(gpointer data) { |
361 |
GnomeVFSFileSize bytes_read; |
GnomeVFSFileSize bytes_read; |
362 |
GnomeVFSResult vfs_result; |
GnomeVFSResult vfs_result; |
374 |
while(1) { |
while(1) { |
375 |
if(appdata->use_gps) { |
if(appdata->use_gps) { |
376 |
if(!connected) { |
if(!connected) { |
377 |
printf("trying to connect\n"); |
printf("gps: trying to connect\n"); |
378 |
|
|
379 |
if(gps_connect(appdata->gps_state) < 0) |
if(gps_connect(appdata->gps_state) < 0) |
380 |
sleep(10); |
sleep(10); |
400 |
if(vfs_result == GNOME_VFS_OK) { |
if(vfs_result == GNOME_VFS_OK) { |
401 |
str[bytes_read] = 0; |
str[bytes_read] = 0; |
402 |
|
|
403 |
// printf("msg: %s (%d)\n", str, strlen(str)); |
// printf("gps: msg: %s (%d)\n", str, strlen(str)); |
404 |
|
|
405 |
g_mutex_lock(appdata->gps_state->mutex); |
g_mutex_lock(appdata->gps_state->mutex); |
406 |
|
|
407 |
if(!cnt) appdata->gps_state->gpsdata.set &= ~SATELLITE_SET; |
if(!cnt) appdata->gps_state->gpsdata.set &= ~SATELLITE_SET; |
408 |
else appdata->gps_state->gpsdata.set &= |
else appdata->gps_state->gpsdata.set &= |
409 |
~(TIME_SET|TIMERR_SET|LATLON_SET|MODE_SET|STATUS_SET); |
~(LATLON_SET|MODE_SET|STATUS_SET); |
410 |
|
|
411 |
gps_unpack(str, &appdata->gps_state->gpsdata); |
gps_unpack(str, &appdata->gps_state->gpsdata); |
412 |
g_mutex_unlock(appdata->gps_state->mutex); |
g_mutex_unlock(appdata->gps_state->mutex); |
413 |
|
g_idle_add(gps_idle_cb, appdata); |
414 |
} |
} |
415 |
} |
} |
416 |
} |
} |
418 |
} |
} |
419 |
} else { |
} else { |
420 |
if(connected) { |
if(connected) { |
421 |
printf("stopping GPS connection due to user request\n"); |
printf("gps: stopping GPS connection due to user request\n"); |
422 |
gnome_vfs_inet_connection_destroy(appdata->gps_state->iconn, NULL); |
gnome_vfs_inet_connection_destroy(appdata->gps_state->iconn, NULL); |
423 |
|
|
424 |
#ifdef USE_MAEMO |
#ifdef USE_MAEMO |
430 |
} |
} |
431 |
} |
} |
432 |
|
|
433 |
printf("GPS thread ended???\n"); |
printf("gps: thread ended???\n"); |
434 |
return NULL; |
return NULL; |
435 |
} |
} |
436 |
|
|
444 |
} |
} |
445 |
|
|
446 |
void gps_release(appdata_t *appdata) { |
void gps_release(appdata_t *appdata) { |
447 |
|
gps_unregister_all(appdata); |
448 |
#ifdef USE_MAEMO |
#ifdef USE_MAEMO |
449 |
gpsbt_stop(&appdata->gps_state->context); |
gpsbt_stop(&appdata->gps_state->context); |
450 |
#endif |
#endif |
459 |
gps_state->fields = device->fix->fields; |
gps_state->fields = device->fix->fields; |
460 |
|
|
461 |
if(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { |
if(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { |
462 |
gps_state->latitude = device->fix->latitude; |
gps_state->fix.pos.lat = device->fix->latitude; |
463 |
gps_state->longitude = device->fix->longitude; |
gps_state->fix.pos.lon = device->fix->longitude; |
464 |
gps_state->epe = device->fix->eph; |
gps_state->fix.eph = device->fix->eph/100.0; // we want eph in meters |
465 |
} |
} |
466 |
|
|
467 |
if(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET) |
if(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET) |
468 |
gps_state->heading = device->fix->track; |
gps_state->fix.track = device->fix->track; |
469 |
|
|
470 |
/* update list of sattelites */ |
/* update list of sattelites */ |
471 |
|
|
500 |
void gps_init(appdata_t *appdata) { |
void gps_init(appdata_t *appdata) { |
501 |
gps_state_t *gps_state = appdata->gps_state = g_new0(gps_state_t, 1); |
gps_state_t *gps_state = appdata->gps_state = g_new0(gps_state_t, 1); |
502 |
|
|
503 |
printf("GPS init: Using liblocation\n"); |
printf("gps: init: Using liblocation\n"); |
504 |
|
|
505 |
gps_state->device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); |
gps_state->device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); |
506 |
if(!gps_state->device) { |
if(!gps_state->device) { |
507 |
printf("Unable to connect to liblocation\n"); |
printf("gps: Unable to connect to liblocation\n"); |
508 |
return; |
return; |
509 |
} |
} |
510 |
|
|
512 |
g_signal_connect(gps_state->device, "changed", |
g_signal_connect(gps_state->device, "changed", |
513 |
G_CALLBACK(location_changed), gps_state); |
G_CALLBACK(location_changed), gps_state); |
514 |
|
|
|
#if MAEMO_VERSION_MAJOR < 5 |
|
515 |
gps_state->control = location_gpsd_control_get_default(); |
gps_state->control = location_gpsd_control_get_default(); |
516 |
|
|
517 |
if(gps_state->control && gps_state->control->can_control) { |
if(gps_state->control |
518 |
printf("Having control over GPSD and GPS is to be enabled, starting it\n"); |
#if MAEMO_VERSION_MAJOR < 5 |
519 |
|
&& gps_state->control->can_control |
520 |
|
#endif |
521 |
|
) { |
522 |
|
|
523 |
|
printf("gps: Having control over GPSD and GPS is to be enabled, starting it\n"); |
524 |
location_gpsd_control_start(gps_state->control); |
location_gpsd_control_start(gps_state->control); |
525 |
} |
} |
|
#endif |
|
526 |
} |
} |
527 |
|
|
528 |
void gps_release(appdata_t *appdata) { |
void gps_release(appdata_t *appdata) { |
529 |
gps_state_t *gps_state = appdata->gps_state; |
gps_state_t *gps_state = appdata->gps_state; |
530 |
|
gps_unregister_all(appdata); |
531 |
|
|
532 |
if(!gps_state->device) return; |
if(!gps_state->device) return; |
533 |
|
|
534 |
|
if(gps_state->control |
535 |
#if MAEMO_VERSION_MAJOR < 5 |
#if MAEMO_VERSION_MAJOR < 5 |
536 |
if(gps_state->control && gps_state->control->can_control) { |
&& gps_state->control->can_control |
537 |
printf("Having control over GPSD, stopping it\n"); |
#endif |
538 |
|
) { |
539 |
|
printf("gps: Having control over GPSD, stopping it\n"); |
540 |
location_gpsd_control_stop(gps_state->control); |
location_gpsd_control_stop(gps_state->control); |
541 |
} |
} |
|
#endif |
|
542 |
|
|
543 |
/* Disconnect signal */ |
/* Disconnect signal */ |
544 |
g_signal_handler_disconnect(gps_state->device, gps_state->idd_changed); |
g_signal_handler_disconnect(gps_state->device, gps_state->idd_changed); |
558 |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
559 |
return NULL; |
return NULL; |
560 |
|
|
561 |
pos.lat = gps_state->latitude; |
pos.lat = gps_state->fix.pos.lat; |
562 |
pos.lon = gps_state->longitude; |
pos.lon = gps_state->fix.pos.lon; |
563 |
|
|
564 |
return &pos; |
return &pos; |
565 |
} |
} |
570 |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET)) |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET)) |
571 |
return NAN; |
return NAN; |
572 |
|
|
573 |
return gps_state->heading; |
return gps_state->fix.track; |
574 |
} |
} |
575 |
|
|
576 |
float gps_get_epe(appdata_t *appdata) { |
float gps_get_eph(appdata_t *appdata) { |
577 |
gps_state_t *gps_state = appdata->gps_state; |
gps_state_t *gps_state = appdata->gps_state; |
578 |
|
|
579 |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
580 |
return NAN; |
return NAN; |
581 |
|
|
582 |
return gps_state->epe; |
return gps_state->fix.eph; |
583 |
} |
} |
584 |
|
|
585 |
gps_sat_t *gps_get_sats(appdata_t *appdata) { |
gps_sat_t *gps_get_sats(appdata_t *appdata) { |
603 |
|
|
604 |
|
|
605 |
#endif |
#endif |
606 |
|
|
607 |
|
void *gps_register_callback(appdata_t *appdata, gps_cb cb, gpointer data) { |
608 |
|
printf("gps: register gps callback\n"); |
609 |
|
|
610 |
|
if(!appdata->gps_state) |
611 |
|
return NULL; |
612 |
|
|
613 |
|
/* allocate callback info strcuture */ |
614 |
|
gps_cb_t *cb_info = g_new0(gps_cb_t, 1); |
615 |
|
cb_info->cb = cb; |
616 |
|
cb_info->data = data; |
617 |
|
|
618 |
|
/* and insert it into list of callbacks */ |
619 |
|
appdata->gps_state->cb = g_slist_append(appdata->gps_state->cb, cb_info); |
620 |
|
|
621 |
|
return cb_info; |
622 |
|
} |
623 |
|
|
624 |
|
|
625 |
|
void gps_unregister_callback(appdata_t *appdata, void *cb) { |
626 |
|
printf("gps: unregister gps callback\n"); |
627 |
|
|
628 |
|
if(!appdata->gps_state) |
629 |
|
return; |
630 |
|
|
631 |
|
/* the item must be in the list */ |
632 |
|
g_assert(g_slist_find(appdata->gps_state->cb, cb)); |
633 |
|
|
634 |
|
g_free(cb); |
635 |
|
appdata->gps_state->cb = g_slist_remove(appdata->gps_state->cb, cb); |
636 |
|
} |
637 |
|
|
638 |
|
static void gps_unregister_all(appdata_t *appdata) { |
639 |
|
printf("gps: unregister all callbacks: "); |
640 |
|
|
641 |
|
while(appdata->gps_state->cb) { |
642 |
|
printf("."); |
643 |
|
g_free(appdata->gps_state->cb->data); |
644 |
|
appdata->gps_state->cb = g_slist_remove(appdata->gps_state->cb, |
645 |
|
appdata->gps_state->cb->data); |
646 |
|
} |
647 |
|
printf("\n"); |
648 |
|
} |