diff --git a/.gitignore b/.gitignore index 1f059943d..ed419a0b4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ tests/atconfig tests/package.m4 tests/paging/paging_test tests/cipher/cipher_test +tests/sysmobts/sysmobts_test tests/testsuite tests/testsuite.log diff --git a/configure.ac b/configure.ac index 62523564d..5abed700c 100644 --- a/configure.ac +++ b/configure.ac @@ -60,4 +60,5 @@ dnl src/osmo-bts-bb/Makefile tests/Makefile tests/paging/Makefile tests/cipher/Makefile + tests/sysmobts/Makefile Makefile) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index bf2d172c7..c6cd7e404 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -59,6 +59,9 @@ struct gsm_bts_role_bts { uint8_t tc4_ctr; } si; uint8_t radio_link_timeout; + + /* used by the sysmoBTS to adjust band */ + uint8_t auto_band; }; enum lchan_ciph_state { diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index e3a333793..80deed29f 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -4,12 +4,12 @@ LDADD = $(LIBOSMOVTY_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOTRAU_ EXTRA_DIST = misc/sysmobts_mgr.h misc/sysmobts_misc.h misc/sysmobts_par.h \ misc/sysmobts_eeprom.h femtobts.h hw_misc.h l1_fwd.h l1_if.h \ - l1_transp.h eeprom.h + l1_transp.h eeprom.h utils.h bin_PROGRAMS = sysmobts sysmobts-remote l1fwd-proxy sysmobts-mgr COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c sysmobts_vty.c tch.c hw_misc.c calib_file.c \ - eeprom.c calib_fixup.c + eeprom.c calib_fixup.c utils.c sysmobts_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c sysmobts_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index b8c9cd2db..1a15d555f 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -38,6 +38,7 @@ #include "l1_if.h" #include "femtobts.h" +#include "utils.h" enum sapi_cmd_type { SAPI_CMD_ACTIVATE, @@ -68,22 +69,6 @@ static const enum GsmL1_LogChComb_t pchan_to_logChComb[_GSM_PCHAN_MAX] = { [GSM_PCHAN_UNKNOWN] = GsmL1_LogChComb_0, }; -static int band_osmo2femto(enum gsm_band osmo_band) -{ - switch (osmo_band) { - case GSM_BAND_850: - return GsmL1_FreqBand_850; - case GSM_BAND_900: - return GsmL1_FreqBand_900; - case GSM_BAND_1800: - return GsmL1_FreqBand_1800; - case GSM_BAND_1900: - return GsmL1_FreqBand_1900; - default: - return -1; - } -} - static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1) { prim->id = id; @@ -292,7 +277,7 @@ static int trx_init(struct gsm_bts_trx *trx) //return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM); } - femto_band = band_osmo2femto(trx->bts->band); + femto_band = sysmobts_select_femto_band(trx->bts, trx->arfcn); if (femto_band < 0) { LOGP(DL1C, LOGL_ERROR, "Unsupported GSM band %s\n", gsm_band_name(trx->bts->band)); diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c index 4993c51d7..558dcd972 100644 --- a/src/osmo-bts-sysmo/sysmobts_vty.c +++ b/src/osmo-bts-sysmo/sysmobts_vty.c @@ -1,7 +1,7 @@ /* VTY interface for sysmoBTS */ /* (C) 2011 by Harald Welte - * (C) 2012 by Holger Hans Peter Freyther + * (C) 2012,2013 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -57,6 +57,28 @@ static struct gsm_bts *vty_bts; /* configuration */ +DEFUN(cfg_bts_auto_band, cfg_bts_auto_band_cmd, + "auto-band", + "Automatically select band for ARFCN based on configured band\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->auto_band = 1; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd, + "no auto-band", + NO_STR "Automatically select band for ARFCN based on configured band\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->auto_band = 0; + return CMD_SUCCESS; +} + DEFUN(cfg_trx_gsmtap_sapi, cfg_trx_gsmtap_sapi_cmd, "HIDDEN", "HIDDEN") { @@ -412,6 +434,10 @@ DEFUN(no_loopback, no_loopback_cmd, void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts) { + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + if (btsb->auto_band) + vty_out(vty, " auto-band%s", VTY_NEWLINE); } /* FIXME: move to libosmocore ? */ @@ -515,6 +541,9 @@ int bts_model_vty_init(struct gsm_bts *bts) install_element(ENABLE_NODE, &loopback_cmd); install_element(ENABLE_NODE, &no_loopback_cmd); + install_element(BTS_NODE, &cfg_bts_auto_band_cmd); + install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd); + install_element(TRX_NODE, &cfg_trx_clkcal_cmd); install_element(TRX_NODE, &cfg_trx_clkcal_def_cmd); install_element(TRX_NODE, &cfg_trx_clksrc_cmd); diff --git a/src/osmo-bts-sysmo/utils.c b/src/osmo-bts-sysmo/utils.c new file mode 100644 index 000000000..d3ee872ce --- /dev/null +++ b/src/osmo-bts-sysmo/utils.c @@ -0,0 +1,87 @@ +/* + * Helper utilities that are used in OML + * + * (C) 2011 by Harald Welte + * (C) 2013 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License + * along with this program. If not, see . + * + */ + +#include "utils.h" + +#include + +#include "femtobts.h" + +static int band_osmo2femto(enum gsm_band osmo_band) +{ + switch (osmo_band) { + case GSM_BAND_850: + return GsmL1_FreqBand_850; + case GSM_BAND_900: + return GsmL1_FreqBand_900; + case GSM_BAND_1800: + return GsmL1_FreqBand_1800; + case GSM_BAND_1900: + return GsmL1_FreqBand_1900; + default: + return -1; + } +} + +/** + * Select the band that matches the ARFCN. In general the ARFCNs + * for GSM1800 and GSM1900 overlap and one needs to specify the + * rightband. When moving between GSM900/GSM1800 and GSM850/1900 + * modifying the BTS configuration is a bit annoying. The auto-band + * configuration allows to ease with this transition. + */ +int sysmobts_select_femto_band(struct gsm_bts *bts, uint16_t arfcn) +{ + enum gsm_band band; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + if (!btsb->auto_band) + return band_osmo2femto(bts->band); + + /* + * We need to check what will happen now. + */ + band = gsm_arfcn2band(arfcn); + + /* if we are already on the right band return */ + if (band == bts->band) + return band_osmo2femto(bts->band); + + /* Check if it is GSM1800/GSM1900 */ + if (band == GSM_BAND_1800 && bts->band == GSM_BAND_1900) + return band_osmo2femto(bts->band); + + /* + * Now to the actual autobauding. We just want DCS/DCS and + * PCS/PCS for PCS we check for 850/1800 though + */ + if ((band == GSM_BAND_900 && bts->band == GSM_BAND_1800) + || (band == GSM_BAND_1800 && bts->band == GSM_BAND_900) + || (band == GSM_BAND_850 && bts->band == GSM_BAND_1900)) + return band_osmo2femto(band); + if (band == GSM_BAND_1800 && bts->band == GSM_BAND_850) + return band_osmo2femto(GSM_BAND_1900); + + /* give up */ + return -1; +} diff --git a/src/osmo-bts-sysmo/utils.h b/src/osmo-bts-sysmo/utils.h new file mode 100644 index 000000000..4574e221d --- /dev/null +++ b/src/osmo-bts-sysmo/utils.h @@ -0,0 +1,10 @@ +#ifndef SYSMOBTS_UTILS_H +#define SYSMOBTS_UTILS_H + +#include + +struct gsm_bts; + +int sysmobts_select_femto_band(struct gsm_bts *bts, uint16_t arfcn); + +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 1d548f956..5fb128f1f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher +SUBDIRS = paging cipher sysmobts # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/sysmobts/Makefile.am b/tests/sysmobts/Makefile.am new file mode 100644 index 000000000..d884237b1 --- /dev/null +++ b/tests/sysmobts/Makefile.am @@ -0,0 +1,9 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) -I$(top_srcdir)/src/osmo-bts-sysmo +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) -lortp + +noinst_PROGRAMS = sysmobts_test +EXTRA_DIST = sysmobts_test.ok + +sysmobts_test_SOURCES = sysmobts_test.c $(top_srcdir)/src/osmo-bts-sysmo/utils.c +sysmobts_test_LDADD = $(LDADD) diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c new file mode 100644 index 000000000..938bd8ca6 --- /dev/null +++ b/tests/sysmobts/sysmobts_test.c @@ -0,0 +1,122 @@ +/* + * (C) 2013 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License + * along with this program. If not, see . + */ + +#include + +#include "femtobts.h" +#include "utils.h" + +#include + +static int direct_map[][3] = { + { GSM_BAND_850, GsmL1_FreqBand_850, 128 }, + { GSM_BAND_900, GsmL1_FreqBand_900, 1 }, + { GSM_BAND_1800, GsmL1_FreqBand_1800, 600 }, + { GSM_BAND_1900, GsmL1_FreqBand_1900, 600 }, +}; + +static int dcs_to_dcs[][3] = { + { GSM_BAND_900, GsmL1_FreqBand_1800, 600 }, + { GSM_BAND_1800, GsmL1_FreqBand_900, 1 }, + { GSM_BAND_900, -1, 438 }, +}; + +static int pcs_to_pcs[][3] = { + { GSM_BAND_850, GsmL1_FreqBand_1900, 512 }, + { GSM_BAND_1900, GsmL1_FreqBand_850, 128 }, + { GSM_BAND_900, -1, 438 }, +}; + +static void test_sysmobts_auto_band(void) +{ + struct gsm_bts bts; + struct gsm_bts_role_bts btsb; + int i; + + memset(&bts, 0, sizeof(bts)); + memset(&btsb, 0, sizeof(btsb)); + bts.role = &btsb; + + /* start with the current option */ + printf("Testing the no auto-band mapping.\n"); + for (i = 0; i < ARRAY_SIZE(direct_map); ++i) { + uint16_t arfcn; + int res; + + btsb.auto_band = 0; + bts.band = direct_map[i][0]; + arfcn = direct_map[i][2]; + res = sysmobts_select_femto_band(&bts, arfcn); + printf("No auto-band band(%d) arfcn(%u) want(%d) got(%d)\n", + bts.band, arfcn, direct_map[i][1], res); + OSMO_ASSERT(res == direct_map[i][1]); + } + + /* Check if auto-band does not break things */ + printf("Checking the mapping with auto-band.\n"); + for (i = 0; i < ARRAY_SIZE(direct_map); ++i) { + uint16_t arfcn; + int res; + + btsb.auto_band = 1; + bts.band = direct_map[i][0]; + arfcn = direct_map[i][2]; + res = sysmobts_select_femto_band(&bts, arfcn); + printf("Auto-band band(%d) arfcn(%u) want(%d) got(%d)\n", + bts.band, arfcn, direct_map[i][1], res); + OSMO_ASSERT(res == direct_map[i][1]); + } + + /* Check DCS to DCS change */ + printf("Checking DCS to DCS\n"); + for (i = 0; i < ARRAY_SIZE(dcs_to_dcs); ++i) { + uint16_t arfcn; + int res; + + btsb.auto_band = 1; + bts.band = dcs_to_dcs[i][0]; + arfcn = dcs_to_dcs[i][2]; + res = sysmobts_select_femto_band(&bts, arfcn); + printf("DCS to DCS band(%d) arfcn(%u) want(%d) got(%d)\n", + bts.band, arfcn, dcs_to_dcs[i][1], res); + OSMO_ASSERT(res == dcs_to_dcs[i][1]); + } + + /* Check for a PCS to PCS change */ + printf("Checking PCS to PCS\n"); + for (i = 0; i < ARRAY_SIZE(pcs_to_pcs); ++i) { + uint16_t arfcn; + int res; + + btsb.auto_band = 1; + bts.band = pcs_to_pcs[i][0]; + arfcn = pcs_to_pcs[i][2]; + res = sysmobts_select_femto_band(&bts, arfcn); + printf("PCS to PCS band(%d) arfcn(%u) want(%d) got(%d)\n", + bts.band, arfcn, pcs_to_pcs[i][1], res); + OSMO_ASSERT(res == pcs_to_pcs[i][1]); + } +} + +int main(int argc, char **argv) +{ + printf("Testing sysmobts routines\n"); + test_sysmobts_auto_band(); + return 0; +} diff --git a/tests/sysmobts/sysmobts_test.ok b/tests/sysmobts/sysmobts_test.ok new file mode 100644 index 000000000..1f534172b --- /dev/null +++ b/tests/sysmobts/sysmobts_test.ok @@ -0,0 +1,19 @@ +Testing sysmobts routines +Testing the no auto-band mapping. +No auto-band band(1) arfcn(128) want(0) got(0) +No auto-band band(2) arfcn(1) want(1) got(1) +No auto-band band(4) arfcn(600) want(2) got(2) +No auto-band band(8) arfcn(600) want(3) got(3) +Checking the mapping with auto-band. +Auto-band band(1) arfcn(128) want(0) got(0) +Auto-band band(2) arfcn(1) want(1) got(1) +Auto-band band(4) arfcn(600) want(2) got(2) +Auto-band band(8) arfcn(600) want(3) got(3) +Checking DCS to DCS +DCS to DCS band(2) arfcn(600) want(2) got(2) +DCS to DCS band(4) arfcn(1) want(1) got(1) +DCS to DCS band(2) arfcn(438) want(-1) got(-1) +Checking PCS to PCS +PCS to PCS band(1) arfcn(512) want(3) got(3) +PCS to PCS band(8) arfcn(128) want(0) got(0) +PCS to PCS band(2) arfcn(438) want(-1) got(-1)