aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-02-08 22:14:07 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-03-03 16:19:09 +0100
commitb9e5403ef46171f58390757d002a756bd9d2d202 (patch)
tree59e707165a09c9e73e2059813b62f2f9124118b6 /openbsc/src/libbsc
parentb6769b99deb471dc7cb5d26b4d145e42ed7478e1 (diff)
mscsplit: remove bts and lchan pointers from libmsc
The diff between this and master will probably need a lot of review and fixes. The current state does compile, but I expect pretty much everything to be broken now. Future development will reinstate proper functionality piecemeal. The first goal is to get basic signalling to work, then SMS. The voice control (RTP) is completely disabled now (see "#if BEFORE_MSCSPLIT") and will be fixed last AFAICT.
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);