sysmobts: Introduce an auto-band config to ease DCS/DCS, PCS/PCS changes

During development one switches from GSM900 to GSM1800 and GSM850 to
GSM1900. This commit attempts to make this switch more easy.

GSM1800 and GSM1900 have overlapping ARFCNs. This means that the
mapping from bands to arfcn is not injective. Because of that I
removed the code to deduce the band from the ARFCN. This was done
in commit 8c3d807b3f. The auto-band
option allows to move between GSM900/GSM1800 and GSM850/GSM1900.

Add a simple testcase with these auto-band configurations.
This commit is contained in:
Holger Hans Peter Freyther 2013-06-20 17:18:38 +02:00
parent 43b4176f0e
commit f169a75fc4
12 changed files with 287 additions and 21 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -60,4 +60,5 @@ dnl src/osmo-bts-bb/Makefile
tests/Makefile
tests/paging/Makefile
tests/cipher/Makefile
tests/sysmobts/Makefile
Makefile)

View File

@ -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 {

View File

@ -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)

View File

@ -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));

View File

@ -1,7 +1,7 @@
/* VTY interface for sysmoBTS */
/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
* (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);

View File

@ -0,0 +1,87 @@
/*
* Helper utilities that are used in OML
*
* (C) 2011 by Harald Welte <laforge@gnumonks.org>
* (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 <http://www.gnu.org/licenses/>.
*
*/
#include "utils.h"
#include <osmo-bts/bts.h>
#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;
}

View File

@ -0,0 +1,10 @@
#ifndef SYSMOBTS_UTILS_H
#define SYSMOBTS_UTILS_H
#include <stdint.h>
struct gsm_bts;
int sysmobts_select_femto_band(struct gsm_bts *bts, uint16_t arfcn);
#endif

View File

@ -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

View File

@ -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)

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <osmo-bts/bts.h>
#include "femtobts.h"
#include "utils.h"
#include <stdio.h>
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;
}

View File

@ -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)