aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-07-30 11:50:09 +0200
committerHarald Welte <laforge@gnumonks.org>2010-07-30 11:50:09 +0200
commit9fbff4adacd9b7b4c45482c2b7c8ecf900d76ba7 (patch)
treeea681cc496fef2d1556afa1c6d15d16d9f758aec
parent5f827f4edea1a66a5a050edb022be81d2d9f8313 (diff)
[BSC] Add support for configfile-hardcoded System Information messages
-rw-r--r--openbsc/configure.in2
-rw-r--r--openbsc/include/openbsc/gsm_data.h4
-rw-r--r--openbsc/src/bsc_init.c46
-rw-r--r--openbsc/src/bsc_vty.c99
4 files changed, 131 insertions, 20 deletions
diff --git a/openbsc/configure.in b/openbsc/configure.in
index f43f6e61b..50189a4aa 100644
--- a/openbsc/configure.in
+++ b/openbsc/configure.in
@@ -22,7 +22,7 @@ AC_SEARCH_LIBS(gtp_new, gtp,
AM_CONDITIONAL(HAVE_LIBGTP, test "x$GPRS_LIBGTP" != "x")
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.14)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.15)
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.9)
dnl checks for header files
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index a66804533..e276e1eee 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -540,6 +540,10 @@ struct gsm_bts {
} data;
} si_common;
+ /* do we use static (user-defined) system information messages? (bitmask) */
+ uint32_t si_mode_static;
+ /* bitmask of all SI that are present/valid in si_buf */
+ uint32_t si_valid;
/* buffers where we put the pre-computed SI */
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index ce668086d..7d9a520aa 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -787,9 +787,12 @@ static int generate_and_rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i
struct gsm_bts *bts = trx->bts;
int rc;
- rc = gsm_generate_si(bts, i);
- if (rc < 0)
- return rc;
+ /* Only generate SI if this SI is not in "static" (user-defined) mode */
+ if (!(bts->si_mode_static & (1 << i))) {
+ rc = gsm_generate_si(bts, i);
+ if (rc < 0)
+ return rc;
+ }
DEBUGP(DRR, "SI%s: %s\n", gsm_sitype_name(i),
hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
@@ -821,26 +824,31 @@ static int set_system_infos(struct gsm_bts_trx *trx)
ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
bts->si_common.cell_sel_par.neci = bts->network->neci;
+ /* First, we determine which of the SI messages we actually need */
+
if (trx == bts->c0) {
- for (i = SYSINFO_TYPE_1; i <= SYSINFO_TYPE_4; i++) {
- rc = generate_and_rsl_si(trx, i);
- if (rc < 0)
- goto err_out;
- }
- if (bts->gprs.mode != BTS_GPRS_NONE) {
- rc = generate_and_rsl_si(trx, SYSINFO_TYPE_13);
- if (rc < 0)
- goto err_out;
- }
+ /* 1...4 are always present on a C0 TRX */
+ for (i = SYSINFO_TYPE_1; i <= SYSINFO_TYPE_4; i++)
+ bts->si_valid |= (1 << i);
+
+ /* 13 is always present on a C0 TRX of a GPRS BTS */
+ if (bts->gprs.mode != BTS_GPRS_NONE)
+ bts->si_valid |= (1 << SYSINFO_TYPE_13);
}
- rc = generate_and_rsl_si(trx, SYSINFO_TYPE_5);
- if (rc < 0)
- goto err_out;
+ /* 5 and 6 are always present on every TRX */
+ bts->si_valid |= (1 << SYSINFO_TYPE_5);
+ bts->si_valid |= (1 << SYSINFO_TYPE_6);
- rc = generate_and_rsl_si(trx, SYSINFO_TYPE_6);
- if (rc < 0)
- goto err_out;
+ /* Second, we generate and send the selected SI via RSL */
+ for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
+ if (!(bts->si_valid & (1 << i)))
+ continue;
+
+ rc = generate_and_rsl_si(trx, i);
+ if (rc < 0)
+ goto err_out;
+ }
return 0;
err_out:
diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c
index a308ec475..739fd8c57 100644
--- a/openbsc/src/bsc_vty.c
+++ b/openbsc/src/bsc_vty.c
@@ -34,6 +34,7 @@
#include <openbsc/gsm_data.h>
#include <openbsc/e1_input.h>
#include <openbsc/abis_nm.h>
+#include <osmocore/utils.h>
#include <osmocore/gsm_utils.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/meas_rep.h>
@@ -41,6 +42,7 @@
#include <osmocore/talloc.h>
#include <openbsc/vty.h>
#include <openbsc/gprs_ns.h>
+#include <openbsc/system_information.h>
#include <openbsc/debug.h>
#include "../bscconfig.h"
@@ -225,6 +227,8 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
VTY_NEWLINE);
if (bts->si_common.rach_control.cell_bar)
vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
+ vty_out(vty, "System Information present: 0x%08x, static: 0x%08x%s",
+ bts->si_valid, bts->si_mode_static, VTY_NEWLINE);
if (is_ipaccess_bts(bts))
vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
bts->ip_access.site_id, bts->ip_access.bts_id,
@@ -386,6 +390,7 @@ static void config_write_bts_gprs(struct vty *vty, struct gsm_bts *bts)
static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
{
struct gsm_bts_trx *trx;
+ int i;
vty_out(vty, " bts %u%s", bts->nr, VTY_NEWLINE);
vty_out(vty, " type %s%s", btstype2str(bts->type), VTY_NEWLINE);
@@ -424,6 +429,16 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
if ((bts->si_common.rach_control.t2 & 0x4) == 0)
vty_out(vty, " rach emergency call allowed 1%s", VTY_NEWLINE);
+ for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
+ if (bts->si_mode_static & (1 << i)) {
+ vty_out(vty, " system-information %s mode static%s",
+ get_value_string(osmo_sitype_strs, i), VTY_NEWLINE);
+ vty_out(vty, " system-information %s static %s%s",
+ get_value_string(osmo_sitype_strs, i),
+ hexdump_nospc(bts->si_buf[i], sizeof(bts->si_buf[i])),
+ VTY_NEWLINE);
+ }
+ }
if (is_ipaccess_bts(bts)) {
vty_out(vty, " ip.access unit_id %u %u%s",
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
@@ -1838,6 +1853,88 @@ DEFUN(cfg_bts_gprs_mode, cfg_bts_gprs_mode_cmd,
return CMD_SUCCESS;
}
+#define SI_TEXT "System Information Messages\n"
+#define SI_TYPE_TEXT "(1|2|3|4|5|6|7|8|9|10|13|16|17|18|19|20|2bis|2ter|2quater|5bis|5ter)"
+#define SI_TYPE_HELP "System Information Type 1\n" \
+ "System Information Type 2\n" \
+ "System Information Type 3\n" \
+ "System Information Type 4\n" \
+ "System Information Type 5\n" \
+ "System Information Type 6\n" \
+ "System Information Type 7\n" \
+ "System Information Type 8\n" \
+ "System Information Type 9\n" \
+ "System Information Type 10\n" \
+ "System Information Type 13\n" \
+ "System Information Type 16\n" \
+ "System Information Type 17\n" \
+ "System Information Type 18\n" \
+ "System Information Type 19\n" \
+ "System Information Type 20\n" \
+ "System Information Type 2bis\n" \
+ "System Information Type 2ter\n" \
+ "System Information Type 2quater\n" \
+ "System Information Type 5bis\n" \
+ "System Information Type 5ter\n"
+
+DEFUN(cfg_bts_si_mode, cfg_bts_si_mode_cmd,
+ "system-information " SI_TYPE_TEXT " mode (static|computed)",
+ SI_TEXT SI_TYPE_HELP
+ "System Information Mode\n"
+ "Static user-specified\n"
+ "Dynamic, BSC-computed\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int type;
+
+ type = get_string_value(osmo_sitype_strs, argv[0]);
+ if (type < 0) {
+ vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!strcmp(argv[1], "static"))
+ bts->si_mode_static |= (1 << type);
+ else
+ bts->si_mode_static &= ~(1 << type);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
+ "system-information " SI_TYPE_TEXT " static HEXSTRING",
+ SI_TEXT SI_TYPE_HELP
+ "Static System Information filling\n"
+ "Static user-specified SI content in HEX notation\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int rc, type;
+
+ type = get_string_value(osmo_sitype_strs, argv[0]);
+ if (type < 0) {
+ vty_out(vty, "Error SI Type%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (!(bts->si_mode_static & (1 << type))) {
+ vty_out(vty, "SI Type %s is not configured in static mode%s",
+ get_value_string(osmo_sitype_strs, type), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rc = hexparse(argv[1], bts->si_buf[type], sizeof(bts->si_buf[0]));
+ if (rc < 0 || rc > sizeof(bts->si_buf[0])) {
+ vty_out(vty, "Error parsing HEXSTRING%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ /* Mark this SI as present */
+ bts->si_valid |= (1 << type);
+
+ return CMD_SUCCESS;
+}
+
+
#define TRX_TEXT "Radio Transceiver\n"
/* per TRX configuration */
@@ -2223,6 +2320,8 @@ int bsc_vty_init(void)
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_lport_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rport_cmd);
install_element(BTS_NODE, &cfg_bts_gprs_nsvc_rip_cmd);
+ install_element(BTS_NODE, &cfg_bts_si_mode_cmd);
+ install_element(BTS_NODE, &cfg_bts_si_static_cmd);
install_element(BTS_NODE, &cfg_trx_cmd);
install_node(&trx_node, dummy_config_write);