summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDario Lombardo <dario.lombardo@libero.it>2011-02-10 14:24:53 +0100
committerHarald Welte <laforge@gnumonks.org>2011-02-16 15:15:12 +0100
commitb7a4d8d9128076d83bd70157299ef0a7a8717a0c (patch)
tree60e6f8f442c72b86e8831687fb71b0168ff6494d
parent26ff2ee8802d7c8e8980d7c4cbfcd9053c6f3091 (diff)
Added gpsd support.
-rw-r--r--src/host/layer23/configure.ac1
-rw-r--r--src/host/layer23/include/osmocom/bb/common/gps.h6
-rw-r--r--src/host/layer23/src/common/gps.c106
-rw-r--r--src/host/layer23/src/misc/app_cell_log.c32
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c41
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 <errno.h>
#include <time.h>
+#ifdef _USE_GPSD
+#include <gps.h>
+#endif
+
#include <osmocore/utils.h>
#include <osmocom/bb/common/osmocom_data.h>
@@ -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);