summaryrefslogtreecommitdiffstats
path: root/src/host
diff options
context:
space:
mode:
authorAndreas.Eversberg2010-08-10 21:56:59 +0200
committerAndreas.Eversberg2010-08-10 21:56:59 +0200
commitcb73be0d0cfa6f5f2c8b437fa3ceb80909199302 (patch)
tree2f35b914eeda3175520d8ebf01744737e8242439 /src/host
parentAdded sequence number to L3 messages (see GSM 04.08 Clause 3.1.4.3) (diff)
downloadosmocom-cb73be0d0cfa6f5f2c8b437fa3ceb80909199302.tar.gz
osmocom-cb73be0d0cfa6f5f2c8b437fa3ceb80909199302.tar.xz
osmocom-cb73be0d0cfa6f5f2c8b437fa3ceb80909199302.zip
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.
Diffstat (limited to 'src/host')
-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 0000000..a62eab7
--- /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 5dbda72..055b3c2 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 4599f99..9a98f89 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 0000000..520aff8
--- /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 426c0d8..0c20731 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);