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 |
} |
} |
187 |
fixp->altitude = NAN; |
fixp->altitude = NAN; |
188 |
fixp->ept = NAN; |
fixp->ept = NAN; |
189 |
fixp->eph = NAN; |
fixp->eph = NAN; |
|
fixp->epv = NAN; |
|
190 |
fixp->epd = NAN; |
fixp->epd = NAN; |
191 |
fixp->eps = NAN; |
fixp->eps = NAN; |
192 |
fixp->epc = NAN; |
fixp->epc = NAN; |
217 |
/* C - cycle isn't supported by gpxview */ |
/* C - cycle isn't supported by gpxview */ |
218 |
/* D - utc time isn't supported by gpxview */ |
/* D - utc time isn't supported by gpxview */ |
219 |
case 'E': |
case 'E': |
220 |
gpsdata->epe = gpsdata->fix.eph = gpsdata->fix.epv = NAN; |
gpsdata->fix.eph = NAN; |
221 |
/* epe should always be present if eph or epv is */ |
/* epe should always be present if eph or epv is */ |
222 |
if (sp[2] != '?') { |
if (sp[2] != '?') { |
223 |
char epe[20], eph[20], epv[20]; |
char epe[20], eph[20], epv[20]; |
224 |
(void)sscanf(sp, "E=%s %s %s", epe, eph, epv); |
(void)sscanf(sp, "E=%s %s %s", epe, eph, epv); |
225 |
#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); |
|
226 |
gpsdata->fix.eph = DEFAULT(eph); |
gpsdata->fix.eph = DEFAULT(eph); |
|
gpsdata->fix.epv = DEFAULT(epv); |
|
227 |
#undef DEFAULT |
#undef DEFAULT |
228 |
} |
} |
229 |
break; |
break; |
264 |
nf.ept = DEFAULT(ept); |
nf.ept = DEFAULT(ept); |
265 |
nf.altitude = DEFAULT(alt); |
nf.altitude = DEFAULT(alt); |
266 |
nf.eph = DEFAULT(eph); |
nf.eph = DEFAULT(eph); |
|
nf.epv = DEFAULT(epv); |
|
267 |
nf.track = DEFAULT(track); |
nf.track = DEFAULT(track); |
268 |
nf.speed = DEFAULT(speed); |
nf.speed = DEFAULT(speed); |
269 |
nf.climb = DEFAULT(climb); |
nf.climb = DEFAULT(climb); |
279 |
gpsdata->set |= ALTITUDE_SET | CLIMB_SET; |
gpsdata->set |= ALTITUDE_SET | CLIMB_SET; |
280 |
if (isnan(nf.eph)==0) |
if (isnan(nf.eph)==0) |
281 |
gpsdata->set |= HERR_SET; |
gpsdata->set |= HERR_SET; |
|
if (isnan(nf.epv)==0) |
|
|
gpsdata->set |= VERR_SET; |
|
282 |
if (isnan(nf.track)==0) |
if (isnan(nf.track)==0) |
283 |
gpsdata->set |= TRACK_SET | SPEED_SET; |
gpsdata->set |= TRACK_SET | SPEED_SET; |
284 |
if (isnan(nf.eps)==0) |
if (isnan(nf.eps)==0) |
378 |
for (j = 0; j < gpsdata->satellites; j++) { |
for (j = 0; j < gpsdata->satellites; j++) { |
379 |
PRN[j]=elevation[j]=azimuth[j]=ss[j]=used[j]=0; |
PRN[j]=elevation[j]=azimuth[j]=ss[j]=used[j]=0; |
380 |
} |
} |
381 |
// printf("sats = %d\n", gpsdata->satellites); |
// printf("gps: sats = %d\n", gpsdata->satellites); |
382 |
for (j = 0, gpsdata->satellites_used = 0; j < gpsdata->satellites; j++) { |
for (j = 0, gpsdata->satellites_used = 0; j < gpsdata->satellites; j++) { |
383 |
if ((sp != NULL) && ((sp = strchr(sp, ':')) != NULL)) { |
if ((sp != NULL) && ((sp = strchr(sp, ':')) != NULL)) { |
384 |
sp++; |
sp++; |
406 |
} |
} |
407 |
} |
} |
408 |
|
|
409 |
|
/* call one of the application provided gps callbacks */ |
410 |
|
static void do_app_cb(gpointer data, gpointer user_data) { |
411 |
|
appdata_t *appdata = (appdata_t*)user_data; |
412 |
|
gps_cb_t *cb = (gps_cb_t*)data; |
413 |
|
cb->cb(appdata->gps_state, cb->data); |
414 |
|
} |
415 |
|
|
416 |
|
/* walk though list of all application provided callbacks */ |
417 |
|
static gboolean gps_idle_cb(gpointer data) { |
418 |
|
appdata_t *appdata = (appdata_t*)data; |
419 |
|
// printf("gps: idle callback, calling app callbacks\n"); |
420 |
|
|
421 |
|
g_slist_foreach(appdata->gps_state->cb, do_app_cb, appdata); |
422 |
|
|
423 |
|
return FALSE; |
424 |
|
} |
425 |
|
|
426 |
gpointer gps_thread(gpointer data) { |
gpointer gps_thread(gpointer data) { |
427 |
GnomeVFSFileSize bytes_read; |
GnomeVFSFileSize bytes_read; |
428 |
GnomeVFSResult vfs_result; |
GnomeVFSResult vfs_result; |
440 |
while(1) { |
while(1) { |
441 |
if(appdata->use_gps) { |
if(appdata->use_gps) { |
442 |
if(!connected) { |
if(!connected) { |
443 |
printf("trying to connect\n"); |
printf("gps: trying to connect\n"); |
444 |
|
|
445 |
if(gps_connect(appdata->gps_state) < 0) |
if(gps_connect(appdata->gps_state) < 0) |
446 |
sleep(10); |
sleep(10); |
466 |
if(vfs_result == GNOME_VFS_OK) { |
if(vfs_result == GNOME_VFS_OK) { |
467 |
str[bytes_read] = 0; |
str[bytes_read] = 0; |
468 |
|
|
469 |
// printf("msg: %s (%d)\n", str, strlen(str)); |
// printf("gps: msg: %s (%d)\n", str, strlen(str)); |
470 |
|
|
471 |
g_mutex_lock(appdata->gps_state->mutex); |
g_mutex_lock(appdata->gps_state->mutex); |
472 |
|
|
476 |
|
|
477 |
gps_unpack(str, &appdata->gps_state->gpsdata); |
gps_unpack(str, &appdata->gps_state->gpsdata); |
478 |
g_mutex_unlock(appdata->gps_state->mutex); |
g_mutex_unlock(appdata->gps_state->mutex); |
479 |
|
g_idle_add(gps_idle_cb, appdata); |
480 |
} |
} |
481 |
} |
} |
482 |
} |
} |
484 |
} |
} |
485 |
} else { |
} else { |
486 |
if(connected) { |
if(connected) { |
487 |
printf("stopping GPS connection due to user request\n"); |
printf("gps: stopping GPS connection due to user request\n"); |
488 |
gnome_vfs_inet_connection_destroy(appdata->gps_state->iconn, NULL); |
gnome_vfs_inet_connection_destroy(appdata->gps_state->iconn, NULL); |
489 |
|
|
490 |
#ifdef USE_MAEMO |
#ifdef USE_MAEMO |
496 |
} |
} |
497 |
} |
} |
498 |
|
|
499 |
printf("GPS thread ended???\n"); |
printf("gps: thread ended???\n"); |
500 |
return NULL; |
return NULL; |
501 |
} |
} |
502 |
|
|
510 |
} |
} |
511 |
|
|
512 |
void gps_release(appdata_t *appdata) { |
void gps_release(appdata_t *appdata) { |
513 |
|
gps_unregister_all(appdata); |
514 |
#ifdef USE_MAEMO |
#ifdef USE_MAEMO |
515 |
gpsbt_stop(&appdata->gps_state->context); |
gpsbt_stop(&appdata->gps_state->context); |
516 |
#endif |
#endif |
527 |
if(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { |
if(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { |
528 |
gps_state->latitude = device->fix->latitude; |
gps_state->latitude = device->fix->latitude; |
529 |
gps_state->longitude = device->fix->longitude; |
gps_state->longitude = device->fix->longitude; |
530 |
gps_state->epe = device->fix->eph; |
gps_state->eph = device->fix->eph/100.0; // we want eph in meters |
531 |
} |
} |
532 |
|
|
533 |
if(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET) |
if(gps_state->fields & LOCATION_GPS_DEVICE_TRACK_SET) |
566 |
void gps_init(appdata_t *appdata) { |
void gps_init(appdata_t *appdata) { |
567 |
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); |
568 |
|
|
569 |
printf("GPS init: Using liblocation\n"); |
printf("gps: init: Using liblocation\n"); |
570 |
|
|
571 |
gps_state->device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); |
gps_state->device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); |
572 |
if(!gps_state->device) { |
if(!gps_state->device) { |
573 |
printf("Unable to connect to liblocation\n"); |
printf("gps: Unable to connect to liblocation\n"); |
574 |
return; |
return; |
575 |
} |
} |
576 |
|
|
578 |
g_signal_connect(gps_state->device, "changed", |
g_signal_connect(gps_state->device, "changed", |
579 |
G_CALLBACK(location_changed), gps_state); |
G_CALLBACK(location_changed), gps_state); |
580 |
|
|
581 |
|
gps_state->control = location_gpsd_control_get_default(); |
582 |
|
|
583 |
|
if(gps_state->control |
584 |
|
#if MAEMO_VERSION_MAJOR < 5 |
585 |
|
&& gps_state->control->can_control |
586 |
|
#endif |
587 |
|
) { |
588 |
|
|
589 |
|
printf("gps: Having control over GPSD and GPS is to be enabled, starting it\n"); |
590 |
|
location_gpsd_control_start(gps_state->control); |
591 |
|
} |
592 |
} |
} |
593 |
|
|
594 |
void gps_release(appdata_t *appdata) { |
void gps_release(appdata_t *appdata) { |
595 |
gps_state_t *gps_state = appdata->gps_state; |
gps_state_t *gps_state = appdata->gps_state; |
596 |
|
gps_unregister_all(appdata); |
597 |
|
|
598 |
if(!gps_state->device) return; |
if(!gps_state->device) return; |
599 |
|
|
600 |
|
if(gps_state->control |
601 |
|
#if MAEMO_VERSION_MAJOR < 5 |
602 |
|
&& gps_state->control->can_control |
603 |
|
#endif |
604 |
|
) { |
605 |
|
printf("gps: Having control over GPSD, stopping it\n"); |
606 |
|
location_gpsd_control_stop(gps_state->control); |
607 |
|
} |
608 |
|
|
609 |
/* Disconnect signal */ |
/* Disconnect signal */ |
610 |
g_signal_handler_disconnect(gps_state->device, gps_state->idd_changed); |
g_signal_handler_disconnect(gps_state->device, gps_state->idd_changed); |
639 |
return gps_state->heading; |
return gps_state->heading; |
640 |
} |
} |
641 |
|
|
642 |
float gps_get_epe(appdata_t *appdata) { |
float gps_get_eph(appdata_t *appdata) { |
643 |
gps_state_t *gps_state = appdata->gps_state; |
gps_state_t *gps_state = appdata->gps_state; |
644 |
|
|
645 |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
if(!(gps_state->fields & LOCATION_GPS_DEVICE_LATLONG_SET)) |
646 |
return NAN; |
return NAN; |
647 |
|
|
648 |
return gps_state->epe; |
return gps_state->eph; |
649 |
} |
} |
650 |
|
|
651 |
gps_sat_t *gps_get_sats(appdata_t *appdata) { |
gps_sat_t *gps_get_sats(appdata_t *appdata) { |
669 |
|
|
670 |
|
|
671 |
#endif |
#endif |
672 |
|
|
673 |
|
void *gps_register_callback(appdata_t *appdata, gps_cb cb, gpointer data) { |
674 |
|
printf("gps: register gps callback\n"); |
675 |
|
|
676 |
|
if(!appdata->gps_state) |
677 |
|
return NULL; |
678 |
|
|
679 |
|
/* allocate callback info strcuture */ |
680 |
|
gps_cb_t *cb_info = g_new0(gps_cb_t, 1); |
681 |
|
cb_info->cb = cb; |
682 |
|
cb_info->data = data; |
683 |
|
|
684 |
|
/* and insert it into list of callbacks */ |
685 |
|
appdata->gps_state->cb = g_slist_append(appdata->gps_state->cb, cb_info); |
686 |
|
|
687 |
|
return cb_info; |
688 |
|
} |
689 |
|
|
690 |
|
|
691 |
|
void gps_unregister_callback(appdata_t *appdata, void *cb) { |
692 |
|
printf("gps: unregister gps callback\n"); |
693 |
|
|
694 |
|
if(!appdata->gps_state) |
695 |
|
return; |
696 |
|
|
697 |
|
/* the item must be in the list */ |
698 |
|
g_assert(g_slist_find(appdata->gps_state->cb, cb)); |
699 |
|
|
700 |
|
g_free(cb); |
701 |
|
appdata->gps_state->cb = g_slist_remove(appdata->gps_state->cb, cb); |
702 |
|
} |
703 |
|
|
704 |
|
static void gps_unregister_all(appdata_t *appdata) { |
705 |
|
printf("gps: unregister all callbacks: "); |
706 |
|
|
707 |
|
while(appdata->gps_state->cb) { |
708 |
|
printf("."); |
709 |
|
g_free(appdata->gps_state->cb->data); |
710 |
|
appdata->gps_state->cb = g_slist_remove(appdata->gps_state->cb, |
711 |
|
appdata->gps_state->cb->data); |
712 |
|
} |
713 |
|
printf("\n"); |
714 |
|
} |