From 9acc82ce4a01d502db1be8cdf15d2328ae181c5c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 22 Dec 2014 18:24:57 +0100 Subject: [PATCH] sysmobts: Initial version to use libgps to determine FIX state We should only calibrate the clock if there is a GPS fix. Start gpsd to determine if there is a fix or not. Work around trimble decoding issues (sent an email upstream). We need to gain some more experience to see if there memory leaks. We also need to re-schedule the calibration depending on the outcome. --- configure.ac | 1 + src/osmo-bts-sysmo/Makefile.am | 4 +- src/osmo-bts-sysmo/misc/sysmobts_mgr.h | 9 ++ src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c | 106 ++++++++++++++++++- 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 25a48b46a..641a6c9a2 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 0.0.7) PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.3) PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl) PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis) +PKG_CHECK_MODULES(LIBGPS, libgps) AC_MSG_CHECKING([whether to enable sysmocom-bts hardware support]) AC_ARG_ENABLE(sysmocom-bts, diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 0edaa27d6..68e3ce64b 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) -lortp EXTRA_DIST = misc/sysmobts_mgr.h misc/sysmobts_misc.h misc/sysmobts_par.h \ @@ -29,7 +29,7 @@ sysmobts_mgr_SOURCES = \ misc/sysmobts_mgr_temp.c \ misc/sysmobts_mgr_calib.c \ eeprom.c -sysmobts_mgr_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a +sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(top_builddir)/src/common/libbts.a sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c eeprom.c sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h index 856173047..3999ffb4b 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h @@ -4,8 +4,11 @@ #include #include +#include #include +#include + #include enum { @@ -88,6 +91,12 @@ struct sysmobts_mgr_instance { int state; struct osmo_timer_list timer; uint32_t last_seqno; + + /* gps structure to see if there is a fix */ + int gps_open; + struct osmo_fd gpsfd; + struct gps_data_t gpsdata; + struct osmo_timer_list fix_timeout; } calib; }; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c index cc011121c..5e16f8ddc 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c @@ -36,15 +36,110 @@ #include #include +static void calib_state_reset(struct sysmobts_mgr_instance *mgr); +static void request_clock_reset(struct sysmobts_mgr_instance *mgr); static void bts_updown_cb(struct ipa_client_conn *link, int up); enum calib_state { CALIB_INITIAL, + CALIB_GPS_WAIT_FOR_FIX, CALIB_CTR_RESET, CALIB_CTR_WAIT, CALIB_COR_SET, }; +static void mgr_gps_close(struct sysmobts_mgr_instance *mgr) +{ + if (!mgr->calib.gps_open) + return; + + osmo_timer_del(&mgr->calib.fix_timeout); + + osmo_fd_unregister(&mgr->calib.gpsfd); + gps_close(&mgr->calib.gpsdata); + memset(&mgr->calib.gpsdata, 0, sizeof(mgr->calib.gpsdata)); + mgr->calib.gps_open = 0; +} + +static void mgr_gps_checkfix(struct sysmobts_mgr_instance *mgr) +{ + struct gps_data_t *data = &mgr->calib.gpsdata; + + /* No 2D fix yet */ + if (data->fix.mode < MODE_2D) { + LOGP(DCALIB, LOGL_DEBUG, "Fix mode not enough: %d\n", + data->fix.mode); + return; + } + + /* The trimble driver is broken...add some sanity checking */ + if (data->satellites_used < 1) { + LOGP(DCALIB, LOGL_DEBUG, "Not enough satellites used: %d\n", + data->satellites_used); + return; + } + + LOGP(DCALIB, LOGL_NOTICE, "Got a GPS fix continuing.\n"); + osmo_timer_del(&mgr->calib.fix_timeout); + mgr_gps_close(mgr); + request_clock_reset(mgr); +} + +static int mgr_gps_read(struct osmo_fd *fd, unsigned int what) +{ + int rc; + struct sysmobts_mgr_instance *mgr = fd->data; + + rc = gps_read(&mgr->calib.gpsdata); + if (rc == -1) { + LOGP(DCALIB, LOGL_ERROR, "gpsd vanished during read.\n"); + calib_state_reset(mgr); + return -1; + } + + if (rc > 0) + mgr_gps_checkfix(mgr); + return 0; +} + +static void mgr_gps_fix_timeout(void *_data) +{ + struct sysmobts_mgr_instance *mgr = _data; + + LOGP(DCALIB, LOGL_ERROR, "Failed to acquire GPRS fix.\n"); + calib_state_reset(mgr); +} + +static void mgr_gps_open(struct sysmobts_mgr_instance *mgr) +{ + int rc; + + rc = gps_open("localhost", DEFAULT_GPSD_PORT, &mgr->calib.gpsdata); + if (rc != 0) { + LOGP(DCALIB, LOGL_ERROR, "Failed to connect to GPS %d\n", rc); + calib_state_reset(mgr); + return; + } + + mgr->calib.gps_open = 1; + gps_stream(&mgr->calib.gpsdata, WATCH_ENABLE, NULL); + + mgr->calib.gpsfd.data = mgr; + mgr->calib.gpsfd.cb = mgr_gps_read; + mgr->calib.gpsfd.when = BSC_FD_READ | BSC_FD_EXCEPT; + mgr->calib.gpsfd.fd = mgr->calib.gpsdata.gps_fd; + if (osmo_fd_register(&mgr->calib.gpsfd) < 0) { + LOGP(DCALIB, LOGL_ERROR, "Failed to register GPSD fd\n"); + calib_state_reset(mgr); + } + + mgr->calib.state = CALIB_GPS_WAIT_FOR_FIX; + mgr->calib.fix_timeout.data = mgr; + mgr->calib.fix_timeout.cb = mgr_gps_fix_timeout; + osmo_timer_schedule(&mgr->calib.fix_timeout, 60, 0); + LOGP(DCALIB, LOGL_NOTICE, "Opened the GPSD connection waiting for fix\n"); +} + static void send_ctrl_cmd(struct sysmobts_mgr_instance *mgr, struct msgb *msg) { @@ -104,15 +199,22 @@ int sysmobts_mgr_calib_run(struct sysmobts_mgr_instance *mgr) return -2; } + mgr_gps_open(mgr); + return 0; +} + +static void request_clock_reset(struct sysmobts_mgr_instance *mgr) +{ send_set_ctrl_cmd(mgr, "trx.0.clock-info", "1"); mgr->calib.state = CALIB_CTR_RESET; - return 0; } static void calib_state_reset(struct sysmobts_mgr_instance *mgr) { mgr->calib.state = CALIB_INITIAL; osmo_timer_del(&mgr->calib.timer); + + mgr_gps_close(mgr); } static void calib_get_clock_err_cb(void *_data) @@ -213,7 +315,7 @@ static void handle_ctrl_set_cor( LOGP(DCALIB, LOGL_NOTICE, "Calibration process completed\n"); - mgr->calib.state = CALIB_INITIAL; + calib_state_reset(mgr); } static void handle_ctrl(struct sysmobts_mgr_instance *mgr, struct msgb *msg)