From f181a04121053c8d046cf41a98aa4abfc5c89fde Mon Sep 17 00:00:00 2001 From: "Andreas.Eversberg" Date: Wed, 20 Oct 2010 18:09:31 +0000 Subject: [layer23] Completed GPS reading process This includes "double" values of logitude and latitude, as well as time stamp, and if the values are valid or not (GPS fix). --- .../layer23/include/osmocom/bb/common/logging.h | 1 + src/host/layer23/include/osmocom/bb/mobile/gps.h | 12 +++- src/host/layer23/src/mobile/gps.c | 80 +++++++++++++++++++++- 3 files changed, 87 insertions(+), 6 deletions(-) (limited to 'src/host') diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h index 683c6858..eb9f4821 100644 --- a/src/host/layer23/include/osmocom/bb/common/logging.h +++ b/src/host/layer23/include/osmocom/bb/common/logging.h @@ -20,6 +20,7 @@ enum { DSAP, DSUM, DSIM, + DGPS, }; extern const struct log_info log_info; diff --git a/src/host/layer23/include/osmocom/bb/mobile/gps.h b/src/host/layer23/include/osmocom/bb/mobile/gps.h index a62eab77..b3b43351 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gps.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gps.h @@ -20,9 +20,15 @@ */ struct gps { - uint8_t enable; - char device[32]; - uint32_t baud; + /* GPS device */ + uint8_t enable; + char device[32]; + uint32_t baud; + + /* current data */ + uint8_t valid; /* we have a fix */ + time_t gmt; /* GMT time when position was received */ + double latitude, longitude; }; extern struct gps gps; diff --git a/src/host/layer23/src/mobile/gps.c b/src/host/layer23/src/mobile/gps.c index 520aff82..c66da6db 100644 --- a/src/host/layer23/src/mobile/gps.c +++ b/src/host/layer23/src/mobile/gps.c @@ -25,16 +25,22 @@ #include #include #include +#include #include #include +#include #include struct gps gps = { 0, "/dev/ttyACM0", - 0 + 0, + + 0, + 0, + 0,0, }; static struct bsc_fd gps_bfd; @@ -42,6 +48,11 @@ static struct termios gps_termios, gps_old_termios; static int gps_line(char *line) { + time_t gps_now, host_now; + struct tm *tm; + int32_t diff; + double latitude, longitude; + if (!!strncmp(line, "$GPGLL", 6)) return 0; line += 7; @@ -50,8 +61,66 @@ static int gps_line(char *line) line[37] = '\0'; /* ddmm.mmmm,N,dddmm.mmmm,E,hhmmss.mmm,A */ - printf("'%s'\n", line); - + /* valid position */ + if (line[36] != 'A') { + LOGP(DGPS, LOGL_INFO, "%s (invalid)\n", line); + gps.valid = 0; + } + gps.valid = 1; + + /* time stamp */ + gps_now = line[30] - '0'; + gps_now += (line[29] - '0') * 10; + gps_now += (line[28] - '0') * 60; + gps_now += (line[27] - '0') * 600; + gps_now += (line[26] - '0') * 3600; + gps_now += (line[25] - '0') * 36000; + time(&host_now); + /* calculate the number of seconds the host differs from GPS */ + diff = host_now % 86400 - gps_now; + if (diff < 0) + diff += 86400; + if (diff >= 43200) + diff -= 86400; + /* apply the "date" part to the GPS time */ + gps_now = host_now - diff; + gps.gmt = gps_now; + tm = localtime(&gps_now); + + /* position */ + latitude = (double)(line[0] - '0') * 10.0; + latitude += (double)(line[1] - '0'); + latitude += (double)(line[2] - '0') / 6.0; + latitude += (double)(line[3] - '0') / 60.0; + latitude += (double)(line[5] - '0') / 600.0; + latitude += (double)(line[6] - '0') / 6000.0; + latitude += (double)(line[7] - '0') / 60000.0; + latitude += (double)(line[8] - '0') / 600000.0; + if (line[10] == 'S') + latitude = 0.0 - latitude; + gps.latitude = latitude; + longitude = (double)(line[12] - '0') * 100.0; + longitude += (double)(line[13] - '0') * 10.0; + longitude += (double)(line[14] - '0'); + longitude += (double)(line[15] - '0') / 6.0; + longitude += (double)(line[16] - '0') / 60.0; + longitude += (double)(line[18] - '0') / 600.0; + longitude += (double)(line[19] - '0') / 6000.0; + longitude += (double)(line[20] - '0') / 60000.0; + longitude += (double)(line[21] - '0') / 600000.0; + if (line[23] == 'W') + longitude = 360.0 - longitude; + gps.longitude = longitude; + + LOGP(DGPS, LOGL_INFO, "%s\n", line); + LOGP(DGPS, LOGL_INFO, " time=%02d:%02d:%02d %04d-%02d-%02d, " + "diff-to-host=%d, latitude=%do%.4f, longitude=%do%.4f\n", + tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900, + tm->tm_mday, tm->tm_mon + 1, diff, + (int)gps.latitude, + (gps.latitude - ((int)gps.latitude)) * 60.0, + (int)gps.longitude, + (gps.longitude - ((int)gps.longitude)) * 60.0); return 0; } @@ -112,6 +181,9 @@ int gps_open(void) if (gps_bfd.fd > 0) return 0; + + LOGP(DGPS, LOGL_INFO, "Open GPS device '%s'\n", gps.device); + gps_bfd.data = NULL; gps_bfd.when = BSC_FD_READ; gps_bfd.cb = gps_cb; @@ -159,6 +231,8 @@ void gps_close(void) if (gps_bfd.fd <= 0) return; + LOGP(DGPS, LOGL_INFO, "Close GPS device\n"); + bsc_unregister_fd(&gps_bfd); if (isatty(gps_bfd.fd)) -- cgit v1.2.3