aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libbsc')
-rw-r--r--openbsc/src/libbsc/abis_rsl.c13
-rw-r--r--openbsc/src/libbsc/bsc_api.c25
-rw-r--r--openbsc/src/libbsc/bsc_vty.c105
-rw-r--r--openbsc/src/libbsc/handover_decision.c21
-rw-r--r--openbsc/src/libbsc/handover_logic.c5
-rw-r--r--openbsc/src/libbsc/net_init.c3
6 files changed, 115 insertions, 57 deletions
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index 10e15c889..512576455 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -1087,6 +1087,19 @@ static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
}
}
+static struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan)
+{
+ struct gsm_meas_rep *meas_rep;
+
+ meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
+ memset(meas_rep, 0, sizeof(*meas_rep));
+ meas_rep->lchan = lchan;
+ lchan->meas_rep_idx = (lchan->meas_rep_idx + 1)
+ % ARRAY_SIZE(lchan->meas_rep);
+
+ return meas_rep;
+}
+
static int rsl_rx_meas_res(struct msgb *msg)
{
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 99eb16365..f7e3c6428 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -147,7 +147,7 @@ static void assignment_t10_timeout(void *_conn)
conn->secondary_lchan = NULL;
/* inform them about the failure */
- api = conn->bts->network->bsc_api;
+ api = conn->network->bsc_api;
api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
}
@@ -158,7 +158,7 @@ static void handle_mr_config(struct gsm_subscriber_connection *conn,
struct gsm_lchan *lchan, int full_rate)
{
struct bsc_api *api;
- api = conn->bts->network->bsc_api;
+ api = conn->network->bsc_api;
struct amr_multirate_conf *mr;
struct gsm48_multi_rate_conf *mr_conf;
@@ -204,7 +204,8 @@ static int handle_new_assignment(struct gsm_subscriber_connection *conn, int cha
chan_type = full_rate ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H;
- new_lchan = lchan_alloc(conn->bts, chan_type, 0);
+ struct gsm_bts *bts = conn->lchan->ts->trx->bts; // MSCPLIT ??
+ new_lchan = lchan_alloc(bts, chan_type, 0);
if (!new_lchan) {
LOGP(DMSC, LOGL_NOTICE, "No free channel.\n");
@@ -254,7 +255,7 @@ struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan)
/* FIXME: above comment is weird in at least two ways */
conn->via_iface = IFACE_A;
conn->lchan = lchan;
- conn->bts = lchan->ts->trx->bts;
+ conn->network = network;
lchan->conn = conn;
llist_add_tail(&conn->entry, &network->subscr_conns);
return conn;
@@ -392,7 +393,7 @@ static int chan_compat_with_mode(struct gsm_lchan *lchan, int chan_mode, int ful
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_mode, int full_rate)
{
struct bsc_api *api;
- api = conn->bts->network->bsc_api;
+ api = conn->network->bsc_api;
if (!chan_compat_with_mode(conn->lchan, chan_mode, full_rate)) {
if (handle_new_assignment(conn, chan_mode, full_rate) != 0)
@@ -427,7 +428,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
struct msgb *msg)
{
struct gsm48_hdr *gh;
- struct bsc_api *api = conn->bts->network->bsc_api;
+ struct bsc_api *api = conn->network->bsc_api;
if (conn->secondary_lchan != msg->lchan) {
LOGP(DMSC, LOGL_ERROR, "Assignment Compl should occur on second lchan.\n");
@@ -442,8 +443,13 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
}
/* switch TRAU muxer for E1 based BTS from one channel to another */
+#if BEFORE_MSCSPLIT
if (is_e1_bts(conn->bts))
switch_trau_mux(conn->lchan, conn->secondary_lchan);
+#else
+ if (is_e1_bts(conn->lchan->ts->trx->bts))
+ switch_trau_mux(conn->lchan, conn->secondary_lchan);
+#endif
/* swap channels */
osmo_timer_del(&conn->T10);
@@ -452,7 +458,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
conn->lchan = conn->secondary_lchan;
conn->secondary_lchan = NULL;
- if (is_ipaccess_bts(conn->bts) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
+ if (is_ipaccess_bts(conn->lchan->ts->trx->bts) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
rsl_ipacc_crcx(conn->lchan);
api->assign_compl(conn, gh->data[0],
@@ -464,7 +470,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
static void handle_ass_fail(struct gsm_subscriber_connection *conn,
struct msgb *msg)
{
- struct bsc_api *api = conn->bts->network->bsc_api;
+ struct bsc_api *api = conn->network->bsc_api;
uint8_t *rr_failure;
struct gsm48_hdr *gh;
@@ -739,7 +745,6 @@ int gsm0808_clear(struct gsm_subscriber_connection *conn)
conn->lchan = NULL;
conn->secondary_lchan = NULL;
conn->ho_lchan = NULL;
- conn->bts = NULL;
osmo_timer_del(&conn->T10);
@@ -753,7 +758,7 @@ static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id
if (!conn)
return;
- api = conn->bts->network->bsc_api;
+ api = conn->network->bsc_api;
if (!api || !api->sapi_n_reject)
return;
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 7fdee054c..418e43549 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -550,14 +550,6 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " location_area_code %u%s", bts->location_area_code,
VTY_NEWLINE);
vty_out(vty, " base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
- if (bts->tz.override != 0) {
- if (bts->tz.dst)
- vty_out(vty, " timezone %d %d %d%s",
- bts->tz.hr, bts->tz.mn, bts->tz.dst, VTY_NEWLINE);
- else
- vty_out(vty, " timezone %d %d%s",
- bts->tz.hr, bts->tz.mn, VTY_NEWLINE);
- }
vty_out(vty, " ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
vty_out(vty, " cell reselection hysteresis %u%s",
bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
@@ -591,13 +583,6 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
(sp->penalty_time*20)+20, VTY_NEWLINE);
}
- /* Is periodic LU enabled or disabled? */
- if (bts->si_common.chan_desc.t3212 == 0)
- vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
- else
- vty_out(vty, " periodic location update %u%s",
- bts->si_common.chan_desc.t3212 * 6, VTY_NEWLINE);
-
vty_out(vty, " radio-link-timeout %d%s",
get_radio_link_timeout(&bts->si_common.cell_options),
VTY_NEWLINE);
@@ -789,6 +774,22 @@ static int config_write_net(struct vty *vty)
vty_out(vty, " dtx-used %u%s", gsmnet->dtx_enabled, VTY_NEWLINE);
vty_out(vty, " subscriber-keep-in-ram %d%s",
gsmnet->subscr_group->keep_subscr, VTY_NEWLINE);
+ if (gsmnet->tz.override != 0) {
+ if (gsmnet->tz.dst)
+ vty_out(vty, " timezone %d %d %d%s",
+ gsmnet->tz.hr, gsmnet->tz.mn, gsmnet->tz.dst,
+ VTY_NEWLINE);
+ else
+ vty_out(vty, " timezone %d %d%s",
+ gsmnet->tz.hr, gsmnet->tz.mn, VTY_NEWLINE);
+ }
+
+ if (gsmnet->t3212 == 0)
+ vty_out(vty, " no periodic location update%s", VTY_NEWLINE);
+ else
+ vty_out(vty, " periodic location update %u%s",
+ gsmnet->t3212 * 6, VTY_NEWLINE);
+
return CMD_SUCCESS;
}
@@ -1753,10 +1754,10 @@ DEFUN(cfg_bts_bsic,
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_timezone,
- cfg_bts_timezone_cmd,
+DEFUN(cfg_net_timezone,
+ cfg_net_timezone_cmd,
"timezone <-19-19> (0|15|30|45)",
- "Set the Timezone Offset of this BTS\n"
+ "Set the Timezone Offset of the network\n"
"Timezone offset (hours)\n"
"Timezone offset (00 minutes)\n"
"Timezone offset (15 minutes)\n"
@@ -1764,22 +1765,22 @@ DEFUN(cfg_bts_timezone,
"Timezone offset (45 minutes)\n"
)
{
- struct gsm_bts *bts = vty->index;
+ struct gsm_network *net = vty->index;
int tzhr = atoi(argv[0]);
int tzmn = atoi(argv[1]);
- bts->tz.hr = tzhr;
- bts->tz.mn = tzmn;
- bts->tz.dst = 0;
- bts->tz.override = 1;
+ net->tz.hr = tzhr;
+ net->tz.mn = tzmn;
+ net->tz.dst = 0;
+ net->tz.override = 1;
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_timezone_dst,
- cfg_bts_timezone_dst_cmd,
+DEFUN(cfg_net_timezone_dst,
+ cfg_net_timezone_dst_cmd,
"timezone <-19-19> (0|15|30|45) <0-2>",
- "Set the Timezone Offset of this BTS\n"
+ "Set the Timezone Offset of the network\n"
"Timezone offset (hours)\n"
"Timezone offset (00 minutes)\n"
"Timezone offset (15 minutes)\n"
@@ -1788,28 +1789,28 @@ DEFUN(cfg_bts_timezone_dst,
"DST offset (hours)\n"
)
{
- struct gsm_bts *bts = vty->index;
+ struct gsm_network *net = vty->index;
int tzhr = atoi(argv[0]);
int tzmn = atoi(argv[1]);
int tzdst = atoi(argv[2]);
- bts->tz.hr = tzhr;
- bts->tz.mn = tzmn;
- bts->tz.dst = tzdst;
- bts->tz.override = 1;
+ net->tz.hr = tzhr;
+ net->tz.mn = tzmn;
+ net->tz.dst = tzdst;
+ net->tz.override = 1;
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_no_timezone,
- cfg_bts_no_timezone_cmd,
+DEFUN(cfg_net_no_timezone,
+ cfg_net_no_timezone_cmd,
"no timezone",
NO_STR
- "Disable BTS specific timezone\n")
+ "Disable network timezone override, use system tz\n")
{
- struct gsm_bts *bts = vty->index;
+ struct gsm_network *net = vty->index;
- bts->tz.override = 0;
+ net->tz.override = 0;
return CMD_SUCCESS;
}
@@ -2309,30 +2310,40 @@ DEFUN(cfg_bts_penalty_time_rsvd, cfg_bts_penalty_time_rsvd_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_per_loc_upd, cfg_bts_per_loc_upd_cmd,
+DEFUN(cfg_net_per_loc_upd, cfg_net_per_loc_upd_cmd,
"periodic location update <6-1530>",
"Periodic Location Updating Interval\n"
"Periodic Location Updating Interval\n"
"Periodic Location Updating Interval\n"
"Periodic Location Updating Interval in Minutes\n")
{
- struct gsm_bts *bts = vty->index;
+ struct gsm_network *net = vty->index;
+ struct gsm_bts *bts;
+
+ net->t3212 = atoi(argv[0]) / 6;
- bts->si_common.chan_desc.t3212 = atoi(argv[0]) / 6;
+ llist_for_each_entry(bts, &net->bts_list, list) {
+ bts->si_common.chan_desc.t3212 = net->t3212;
+ }
return CMD_SUCCESS;
}
-DEFUN(cfg_bts_no_per_loc_upd, cfg_bts_no_per_loc_upd_cmd,
+DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
"no periodic location update",
NO_STR
"Periodic Location Updating Interval\n"
"Periodic Location Updating Interval\n"
"Periodic Location Updating Interval\n")
{
- struct gsm_bts *bts = vty->index;
+ struct gsm_network *net = vty->index;
+ struct gsm_bts *bts;
- bts->si_common.chan_desc.t3212 = 0;
+ net->t3212 = 0;
+
+ llist_for_each_entry(bts, &net->bts_list, list) {
+ bts->si_common.chan_desc.t3212 = net->t3212;
+ }
return CMD_SUCCESS;
}
@@ -3772,6 +3783,11 @@ int bsc_vty_init(const struct log_info *cat)
install_element(GSMNET_NODE, &cfg_net_dtx_cmd);
install_element(GSMNET_NODE, &cfg_net_subscr_keep_cmd);
install_element(GSMNET_NODE, &cfg_net_pag_any_tch_cmd);
+ install_element(GSMNET_NODE, &cfg_net_timezone_cmd);
+ install_element(GSMNET_NODE, &cfg_net_timezone_dst_cmd);
+ install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
+ install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
+ install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
install_element(GSMNET_NODE, &cfg_bts_cmd);
install_node(&bts_node, config_write_bts);
@@ -3786,9 +3802,6 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_bsic_cmd);
install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
- install_element(BTS_NODE, &cfg_bts_timezone_cmd);
- install_element(BTS_NODE, &cfg_bts_timezone_dst_cmd);
- install_element(BTS_NODE, &cfg_bts_no_timezone_cmd);
install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
install_element(BTS_NODE, &cfg_bts_nokia_site_no_loc_rel_cnf_cmd);
install_element(BTS_NODE, &cfg_bts_nokia_site_bts_reset_timer_cnf_cmd);
@@ -3807,8 +3820,6 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_rach_ec_allowed_cmd);
install_element(BTS_NODE, &cfg_bts_rach_ac_class_cmd);
install_element(BTS_NODE, &cfg_bts_ms_max_power_cmd);
- install_element(BTS_NODE, &cfg_bts_per_loc_upd_cmd);
- install_element(BTS_NODE, &cfg_bts_no_per_loc_upd_cmd);
install_element(BTS_NODE, &cfg_bts_cell_resel_hyst_cmd);
install_element(BTS_NODE, &cfg_bts_rxlev_acc_min_cmd);
install_element(BTS_NODE, &cfg_bts_cell_bar_qualify_cmd);
diff --git a/openbsc/src/libbsc/handover_decision.c b/openbsc/src/libbsc/handover_decision.c
index 24c0f79cb..2835d893a 100644
--- a/openbsc/src/libbsc/handover_decision.c
+++ b/openbsc/src/libbsc/handover_decision.c
@@ -33,6 +33,27 @@
#include <openbsc/handover.h>
#include <osmocom/gsm/gsm_utils.h>
+/* Get reference to a neighbor cell on a given BCCH ARFCN */
+static struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
+ uint16_t arfcn, uint8_t bsic)
+{
+ struct gsm_bts *neigh;
+ /* FIXME: use some better heuristics here to determine which cell
+ * using this ARFCN really is closest to the target cell. For
+ * now we simply assume that each ARFCN will only be used by one
+ * cell */
+
+ llist_for_each_entry(neigh, &bts->network->bts_list, list) {
+ /* FIXME: this is probably returning the same bts again!? */
+ if (neigh->c0->arfcn == arfcn &&
+ neigh->bsic == bsic)
+ return neigh;
+ }
+
+ return NULL;
+}
+
+
/* issue handover to a cell identified by ARFCN and BSIC */
static int handover_to_arfcn_bsic(struct gsm_lchan *lchan,
uint16_t arfcn, uint8_t bsic)
diff --git a/openbsc/src/libbsc/handover_logic.c b/openbsc/src/libbsc/handover_logic.c
index 2b8c386ed..7ed196651 100644
--- a/openbsc/src/libbsc/handover_logic.c
+++ b/openbsc/src/libbsc/handover_logic.c
@@ -269,9 +269,14 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
osmo_timer_del(&ho->T3103);
+#if BEFORE_MSCSPLIT
/* switch TRAU muxer for E1 based BTS from one channel to another */
if (is_e1_bts(new_lchan->conn->bts))
switch_trau_mux(ho->old_lchan, new_lchan);
+#else
+ if (is_e1_bts(new_lchan->ts->trx->bts))
+ switch_trau_mux(ho->old_lchan, new_lchan);
+#endif
/* Replace the ho lchan with the primary one */
if (ho->old_lchan != new_lchan->conn->lchan)
diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c
index 3b033c7b6..3b5f4f906 100644
--- a/openbsc/src/libbsc/net_init.c
+++ b/openbsc/src/libbsc/net_init.c
@@ -68,6 +68,9 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
net->handover.pwr_hysteresis = 3;
net->handover.max_distance = 9999;
+ /* Use 30 min periodic update interval as sane default */
+ net->t3212 = 5;
+
INIT_LLIST_HEAD(&net->trans_list);
INIT_LLIST_HEAD(&net->upqueue);
INIT_LLIST_HEAD(&net->bts_list);