summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gps.h33
-rw-r--r--src/host/layer23/src/mobile/Makefile.am2
-rw-r--r--src/host/layer23/src/mobile/app_mobile.c2
-rw-r--r--src/host/layer23/src/mobile/gps.c171
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c76
5 files changed, 283 insertions, 1 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/gps.h b/src/host/layer23/include/osmocom/bb/mobile/gps.h
new file mode 100644
index 00000000..a62eab77
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/mobile/gps.h
@@ -0,0 +1,33 @@
+/*
+ * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+struct gps {
+ uint8_t enable;
+ char device[32];
+ uint32_t baud;
+};
+
+extern struct gps gps;
+
+int gps_open(void);
+void gps_close(void);
+
+
diff --git a/src/host/layer23/src/mobile/Makefile.am b/src/host/layer23/src/mobile/Makefile.am
index 5dbda72a..055b3c2a 100644
--- a/src/host/layer23/src/mobile/Makefile.am
+++ b/src/host/layer23/src/mobile/Makefile.am
@@ -4,7 +4,7 @@ LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
noinst_LIBRARIES = libmobile.a
libmobile_a_SOURCES = gsm322.c gsm48_cc.c gsm48_mm.c gsm48_rr.c \
- mnccms.c settings.c subscriber.c support.c \
+ mnccms.c settings.c subscriber.c support.c gps.c \
sysinfo.c transaction.c vty_interface.c
bin_PROGRAMS = mobile
diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c
index 4599f99c..9a98f89f 100644
--- a/src/host/layer23/src/mobile/app_mobile.c
+++ b/src/host/layer23/src/mobile/app_mobile.c
@@ -34,6 +34,7 @@
#include <osmocom/bb/mobile/gsm48_rr.h>
#include <osmocom/bb/mobile/sysinfo.h>
#include <osmocom/bb/mobile/vty.h>
+#include <osmocom/bb/mobile/gps.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocore/msgb.h>
@@ -127,6 +128,7 @@ int mobile_exit(struct osmocom_ms *ms)
signal(SIGPIPE, SIG_DFL);
unregister_signal_handler(SS_L1CTL, &signal_cb, NULL);
+ gps_close();
gsm322_exit(ms);
gsm48_mm_exit(ms);
gsm48_rr_exit(ms);
diff --git a/src/host/layer23/src/mobile/gps.c b/src/host/layer23/src/mobile/gps.c
new file mode 100644
index 00000000..520aff82
--- /dev/null
+++ b/src/host/layer23/src/mobile/gps.c
@@ -0,0 +1,171 @@
+/*
+ * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/file.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <osmocore/utils.h>
+
+#include <osmocom/bb/common/osmocom_data.h>
+#include <osmocom/bb/mobile/gps.h>
+
+struct gps gps = {
+ 0,
+ "/dev/ttyACM0",
+ 0
+};
+
+static struct bsc_fd gps_bfd;
+static struct termios gps_termios, gps_old_termios;
+
+static int gps_line(char *line)
+{
+ if (!!strncmp(line, "$GPGLL", 6))
+ return 0;
+ line += 7;
+ if (strlen(line) < 37)
+ return 0;
+ line[37] = '\0';
+ /* ddmm.mmmm,N,dddmm.mmmm,E,hhmmss.mmm,A */
+
+ printf("'%s'\n", line);
+
+ return 0;
+}
+
+static int nmea_checksum(char *line)
+{
+ uint8_t checksum = 0;
+
+ while (*line) {
+ if (*line == '$') {
+ line++;
+ continue;
+ }
+ if (*line == '*')
+ break;
+ checksum ^= *line++;
+ }
+ return (strtoul(line+1, NULL, 16) == checksum);
+}
+
+int gps_cb(struct bsc_fd *bfd, unsigned int what)
+{
+ char buff[128];
+ static char line[128];
+ static int lpos = 0;
+ int i = 0, len;
+
+ len = read(bfd->fd, buff, sizeof(buff));
+ if (len <= 0) {
+ fprintf(stderr, "error reading GPS device (errno=%d)\n", errno);
+ return len;
+ }
+ while(i < len) {
+ if (buff[i] == 13) {
+ i++;
+ continue;
+ }
+ if (buff[i] == 10) {
+ line[lpos] = '\0';
+ lpos = 0;
+ i++;
+ if (!nmea_checksum(line))
+ fprintf(stderr, "NMEA checksum error\n");
+ else
+ gps_line(line);
+ continue;
+ }
+ line[lpos++] = buff[i++];
+ if (lpos == sizeof(line))
+ lpos--;
+ }
+
+ return 0;
+}
+
+int gps_open(void)
+{
+ int baud = 0;
+
+ if (gps_bfd.fd > 0)
+ return 0;
+ gps_bfd.data = NULL;
+ gps_bfd.when = BSC_FD_READ;
+ gps_bfd.cb = gps_cb;
+ gps_bfd.fd = open(gps.device, O_RDONLY);
+ if (gps_bfd.fd < 0)
+ return gps_bfd.fd;
+
+ switch (gps.baud) {
+ case 4800:
+ baud = B4800; break;
+ case 9600:
+ baud = B9600; break;
+ case 19200:
+ baud = B19200; break;
+ case 38400:
+ baud = B38400; break;
+ case 57600:
+ baud = B57600; break;
+ case 115200:
+ baud = B115200; break;
+ }
+
+ if (isatty(gps_bfd.fd))
+ {
+ /* get termios */
+ tcgetattr(gps_bfd.fd, &gps_old_termios);
+ tcgetattr(gps_bfd.fd, &gps_termios);
+ /* set baud */
+ if (baud) {
+ gps_termios.c_cflag |= baud;
+ cfsetispeed(&gps_termios, baud);
+ cfsetospeed(&gps_termios, baud);
+ }
+ if (tcsetattr(gps_bfd.fd, TCSANOW, &gps_termios))
+ printf("Failed to set termios for GPS\n");
+ }
+
+ bsc_register_fd(&gps_bfd);
+
+ return 0;
+}
+
+void gps_close(void)
+{
+ if (gps_bfd.fd <= 0)
+ return;
+
+ bsc_unregister_fd(&gps_bfd);
+
+ if (isatty(gps_bfd.fd))
+ tcsetattr(gps_bfd.fd, TCSANOW, &gps_old_termios);
+
+ close(gps_bfd.fd);
+ gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
+}
+
+
diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c
index 426c0d82..0c207316 100644
--- a/src/host/layer23/src/mobile/vty_interface.c
+++ b/src/host/layer23/src/mobile/vty_interface.c
@@ -32,6 +32,7 @@
#include <osmocom/bb/mobile/mncc.h>
#include <osmocom/bb/mobile/transaction.h>
#include <osmocom/bb/mobile/vty.h>
+#include <osmocom/bb/mobile/gps.h>
#include <osmocom/vty/telnet_interface.h>
int mncc_call(struct osmocom_ms *ms, char *number);
@@ -526,6 +527,68 @@ DEFUN(network_search, network_search_cmd, "network search MS_NAME",
return CMD_SUCCESS;
}
+DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
+ "GPS receiver")
+{
+ if (gps_open()) {
+ gps.enable = 1;
+ vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ gps.enable = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
+ NO_STR "Disable GPS receiver")
+{
+ if (gps.enable)
+ gps_close();
+ gps.enable = 0;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
+ "GPS receiver\nSelect serial device\n"
+ "Full path of serial device including /dev/")
+{
+ strncpy(gps.device, argv[0], sizeof(gps.device));
+ gps.device[sizeof(gps.device) - 1] = '\0';
+ if (gps.enable) {
+ gps_close();
+ if (gps_open()) {
+ vty_out(vty, "Failed to open GPS device!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+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")
+{
+ if (argv[0][0] == 'd')
+ gps.baud = 0;
+ else
+ gps.baud = atoi(argv[0]);
+ if (gps.enable) {
+ gps_close();
+ if (gps_open()) {
+ gps.enable = 0;
+ vty_out(vty, "Failed to open GPS device!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
/* per MS config */
DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
"Select a mobile station to configure\nName of MS (see \"show ms\")")
@@ -619,6 +682,14 @@ static int config_write_ms(struct vty *vty)
{
struct osmocom_ms *ms;
+ 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);
+ vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
+ vty_out(vty, "!%s", VTY_NEWLINE);
+
llist_for_each_entry(ms, &ms_list, entity)
config_write_ms_single(vty, ms);
@@ -1079,6 +1150,11 @@ int ms_vty_init(void)
install_element(ENABLE_NODE, &call_cmd);
install_element(ENABLE_NODE, &call_retr_cmd);
+ install_element(CONFIG_NODE, &cfg_gps_device_cmd);
+ install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
+ install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
+ install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
+
install_element(CONFIG_NODE, &cfg_ms_cmd);
install_element(CONFIG_NODE, &ournode_end_cmd);
install_node(&ms_node, config_write_ms);