summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-08-10 19:56:59 +0000
committerAndreas.Eversberg <jolly@eversberg.eu>2010-08-10 19:56:59 +0000
commitcb73be0d0cfa6f5f2c8b437fa3ceb80909199302 (patch)
tree2f35b914eeda3175520d8ebf01744737e8242439
parent6439e4f2796deb1498de7d805757bf2b8f56b1c4 (diff)
Added support for NMEA GPS receiver
This early support does not use the received postion, it just dumps it. Later it can be used to set clock of the phone. Also it can be used to calculate the location of a BTS.
-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);