From b7a4d8d9128076d83bd70157299ef0a7a8717a0c Mon Sep 17 00:00:00 2001 From: Dario Lombardo Date: Thu, 10 Feb 2011 14:24:53 +0100 Subject: Added gpsd support. --- src/host/layer23/configure.ac | 1 + src/host/layer23/include/osmocom/bb/common/gps.h | 6 ++ src/host/layer23/src/common/gps.c | 106 ++++++++++++++++++++++- src/host/layer23/src/misc/app_cell_log.c | 32 ++++++- src/host/layer23/src/mobile/vty_interface.c | 41 +++++++++ 5 files changed, 182 insertions(+), 4 deletions(-) diff --git a/src/host/layer23/configure.ac b/src/host/layer23/configure.ac index 1be98eec..e1c718eb 100644 --- a/src/host/layer23/configure.ac +++ b/src/host/layer23/configure.ac @@ -15,6 +15,7 @@ AC_PROG_RANLIB dnl checks for libraries PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore) PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty) +AC_CHECK_LIB(gps, gps_open, CFLAGS+=" -D_USE_GPSD" LDFLAGS+=" -lgps",,) dnl checks for header files AC_HEADER_STDC diff --git a/src/host/layer23/include/osmocom/bb/common/gps.h b/src/host/layer23/include/osmocom/bb/common/gps.h index 467cee52..b7500dbc 100644 --- a/src/host/layer23/include/osmocom/bb/common/gps.h +++ b/src/host/layer23/include/osmocom/bb/common/gps.h @@ -22,8 +22,14 @@ struct osmo_gps { /* GPS device */ uint8_t enable; + +#ifdef _USE_GPSD + char gpsd_host[32]; + char gpsd_port[6]; +#else char device[32]; uint32_t baud; +#endif /* current data */ uint8_t valid; /* we have a fix */ diff --git a/src/host/layer23/src/common/gps.c b/src/host/layer23/src/common/gps.c index dfca3b2b..55dd239e 100644 --- a/src/host/layer23/src/common/gps.c +++ b/src/host/layer23/src/common/gps.c @@ -27,6 +27,10 @@ #include #include +#ifdef _USE_GPSD +#include +#endif + #include #include @@ -35,15 +39,111 @@ struct osmo_gps gps = { 0, +#ifdef _USE_GPSD + "localhost", + "2947", +#else "/dev/ttyACM0", 0, - +#endif 0, 0, - 0,0, + 0,0 }; static struct bsc_fd gps_bfd; + +#ifdef _USE_GPSD + +static struct gps_data_t* gdata; + +int osmo_gps_cb(struct bsc_fd *bfd, unsigned int what) +{ + struct tm *tm; + unsigned diff = 0; + + gps.valid = 0; + + /* gps is offline */ + if (gdata->online) + goto gps_not_ready; + + /* gps has no data */ + if (gps_waiting(gdata)) + goto gps_not_ready; + + /* polling returned an error */ + if (gps_poll(gdata)) + goto gps_not_ready; + + /* data are valid */ + if (gdata->set & LATLON_SET) { + gps.valid = 1; + gps.gmt = gdata->fix.time; + tm = localtime(&gps.gmt); + diff = time(NULL) - gps.gmt; + gps.latitude = gdata->fix.latitude; + gps.longitude = gdata->fix.longitude; + + 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; + +gps_not_ready: + LOGP(DGPS, LOGL_DEBUG, "gps is offline"); + return -1; +} + +int osmo_gps_open(void) +{ + LOGP(DGPS, LOGL_INFO, "Connecting to gpsd at '%s:%s'\n", gps.gpsd_host, gps.gpsd_port); + + gps_bfd.data = NULL; + gps_bfd.when = BSC_FD_READ; + gps_bfd.cb = osmo_gps_cb; + + gdata = gps_open(gps.gpsd_host, gps.gpsd_port); + if (gdata == NULL) { + LOGP(DGPS, LOGL_ERROR, "Can't connect to gpsd\n"); + return -1; + } + gps_bfd.fd = gdata->gps_fd; + if (gps_bfd.fd < 0) + return gps_bfd.fd; + + if (gps_stream(gdata, WATCH_ENABLE, NULL) == -1) { + LOGP(DGPS, LOGL_ERROR, "Error in gps_stream()\n"); + return -1; + } + + bsc_register_fd(&gps_bfd); + + return 0; +} + +void osmo_gps_close(void) +{ + if (gps_bfd.fd <= 0) + return; + + LOGP(DGPS, LOGL_INFO, "Disconnecting from gpsd\n"); + + bsc_unregister_fd(&gps_bfd); + + gps_close(gdata); + gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */ +} + +#else + static struct termios gps_termios, gps_old_termios; static int osmo_gps_line(char *line) @@ -243,6 +343,8 @@ void osmo_gps_close(void) gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */ } +#endif + void osmo_gps_init(void) { memset(&gps_bfd, 0, sizeof(gps_bfd)); diff --git a/src/host/layer23/src/misc/app_cell_log.c b/src/host/layer23/src/misc/app_cell_log.c index 0d612265..7a2c67a8 100644 --- a/src/host/layer23/src/misc/app_cell_log.c +++ b/src/host/layer23/src/misc/app_cell_log.c @@ -92,8 +92,13 @@ static int l23_getopt_options(struct option **options) {"logfile", 1, 0, 'l'}, {"rach", 1, 0, 'r'}, {"no-rach", 1, 0, 'n'}, +#ifdef _USE_GPSD + {"gpsd-host", 1, 0, 'g'}, + {"gpsd-port", 1, 0, 'p'} +#else {"gps", 1, 0, 'g'}, {"baud", 1, 0, 'b'} +#endif }; *options = opts; @@ -103,11 +108,16 @@ static int l23_getopt_options(struct option **options) static int l23_cfg_print_help() { printf("\nApplication specific\n"); - printf(" -l --logfile LOGFILE Logfile for the cell log.\n"); + printf(" -l --logfile LOGFILE Logfile for the cell log.\n"); printf(" -r --rach RACH Nr. of RACH bursts to send.\n"); printf(" -n --no-rach Send no rach bursts.\n"); +#ifdef _USE_GPSD + printf(" -g --gpsd-host HOST 127.0.0.1. gpsd host.\n"); + printf(" -p --port PORT 2947. gpsd port\n"); +#else printf(" -g --gps DEVICE /dev/ttyACM0. GPS device.\n"); printf(" -b --baud BAUDRAT The baud rate of the GPS device\n"); +#endif return 0; } @@ -123,6 +133,20 @@ static int l23_cfg_handle(int c, const char *optarg) case 'n': RACH_MAX = 0; break; +#ifdef _USE_GPSD + case 'g': + snprintf(gps.gpsd_host, ARRAY_SIZE(gps.gpsd_host), "%s", optarg); + /* force string terminator */ + gps.gpsd_host[ARRAY_SIZE(gps.gpsd_host) - 1] = '\0'; + LOGP(DGPS, LOGL_INFO, "Using gpsd host %s\n", gps.gpsd_host); + break; + case 'p': + snprintf(gps.gpsd_port, ARRAY_SIZE(gps.gpsd_port), "%s", optarg); + /* force string terminator */ + gps.gpsd_port[ARRAY_SIZE(gps.gpsd_port) - 1] = '\0'; + LOGP(DGPS, LOGL_INFO, "Using gpsd port %s\n", gps.gpsd_port); + break; +#else case 'g': snprintf(gps.device, ARRAY_SIZE(gps.device), "%s", optarg); /* force string terminator */ @@ -133,14 +157,18 @@ static int l23_cfg_handle(int c, const char *optarg) gps.baud = atoi(optarg); LOGP(DGPS, LOGL_INFO, "Setting GPS baudrate to %u\n", gps.baud); break; +#endif } - return 0; } static struct l23_app_info info = { .copyright = "Copyright (C) 2010 Andreas Eversberg\n", +#ifdef _USE_GPSD + .getopt_string = "l:r:ng:p:", +#else .getopt_string = "l:r:ng:b:", +#endif .cfg_supported = l23_cfg_supported, .cfg_getopt_opt = l23_getopt_options, .cfg_handle_opt = l23_cfg_handle, diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index ecefc894..7888f014 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -855,6 +855,35 @@ DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable", return CMD_SUCCESS; } +#ifdef _USE_GPSD +DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT", + "GPS receiver\nSelect gpsd host and port\n" + "IP and port (optional) of the host running gpsd") +{ + char* colon = strstr(argv[0], ":"); + if (colon != NULL) { + memcpy(gps.gpsd_host, argv[0], colon - argv[0] - 1); + gps.gpsd_host[colon - argv[0]] = '\0'; + memcpy(gps.gpsd_port, colon, strlen(colon)); + gps.gpsd_port[strlen(colon)] = '\0'; + } else { + snprintf(gps.gpsd_host, ARRAY_SIZE(gps.gpsd_host), "%s", argv[0]); + gps.gpsd_host[ARRAY_SIZE(gps.gpsd_host) - 1] = '\0'; + snprintf(gps.gpsd_port, ARRAY_SIZE(gps.gpsd_port), "2947"); + gps.gpsd_port[ARRAY_SIZE(gps.gpsd_port) - 1] = '\0'; + } + if (gps.enable) { + osmo_gps_close(); + if (osmo_gps_open()) { + vty_out(vty, "Failed to connect to gpsd host!%s", + VTY_NEWLINE); + return CMD_WARNING; + } + } + + return CMD_SUCCESS; +} +#else DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE", "GPS receiver\nSelect serial device\n" "Full path of serial device including /dev/") @@ -872,7 +901,9 @@ DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE", return CMD_SUCCESS; } +#endif +#ifndef _USE_GPSD DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate " "(default|4800|""9600|19200|38400|57600|115200)", "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n") @@ -893,6 +924,7 @@ DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate " return CMD_SUCCESS; } +#endif /* per MS config */ DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME", @@ -1172,11 +1204,16 @@ static int config_write(struct vty *vty) { struct osmocom_ms *ms; +#ifdef _USE_GPSD + vty_out(vty, "gpsd host %s%s", gps.gpsd_host, VTY_NEWLINE); + vty_out(vty, "gpsd port %s%s", gps.gpsd_port, VTY_NEWLINE); +#else vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE); if (gps.baud) vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE); else vty_out(vty, "gps baudrate default%s", VTY_NEWLINE); +#endif vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); @@ -2268,8 +2305,12 @@ int ms_vty_init(void) install_element(ENABLE_NODE, &call_retr_cmd); install_element(ENABLE_NODE, &call_dtmf_cmd); +#ifdef _USE_GPSD + install_element(CONFIG_NODE, &cfg_gps_host_cmd); +#else install_element(CONFIG_NODE, &cfg_gps_device_cmd); install_element(CONFIG_NODE, &cfg_gps_baud_cmd); +#endif install_element(CONFIG_NODE, &cfg_gps_enable_cmd); install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd); -- cgit v1.2.3