aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/Makefile.am3
-rw-r--r--openbsc/include/openbsc/common.h10
-rw-r--r--openbsc/include/openbsc/gsm_data.h53
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h17
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h5
-rw-r--r--openbsc/include/openbsc/iu.h7
-rw-r--r--openbsc/include/openbsc/signal.h2
-rw-r--r--openbsc/src/gprs/sgsn_main.c2
-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
-rw-r--r--openbsc/src/libcommon/common_vty.c2
-rw-r--r--openbsc/src/libcommon/gsm_data.c34
-rw-r--r--openbsc/src/libiu/iu.c29
-rw-r--r--openbsc/src/libmsc/Makefile.am3
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c291
-rw-r--r--openbsc/src/libmsc/gsm_04_11.c18
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c22
-rw-r--r--openbsc/src/libmsc/mncc_builtin.c5
-rw-r--r--openbsc/src/libmsc/osmo_msc.c2
-rw-r--r--openbsc/src/libmsc/rrlp.c2
-rw-r--r--openbsc/src/libmsc/silent_call.c4
-rw-r--r--openbsc/src/libmsc/transaction.c4
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c10
-rw-r--r--openbsc/src/osmo-cscn/cscn_main.c4
-rw-r--r--openbsc/src/osmo-cscn/iu_cs.c40
29 files changed, 380 insertions, 361 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index c163a6c2c..907119e04 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -19,7 +19,8 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
gprs_gsup_client.h bsc_msg_filter.h \
oap.h oap_messages.h \
gtphub.h \
- iu.h iu_cs.h
+ iu.h iu_cs.h \
+ common.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
openbscdir = $(includedir)/openbsc
diff --git a/openbsc/include/openbsc/common.h b/openbsc/include/openbsc/common.h
new file mode 100644
index 000000000..3d7de115e
--- /dev/null
+++ b/openbsc/include/openbsc/common.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#define MAX_A5_KEY_LEN (128/8)
+
+struct gsm_encr {
+ uint8_t alg_id;
+ uint8_t key_len;
+ uint8_t key[MAX_A5_KEY_LEN];
+};
+
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 11ecd228a..58647998b 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -7,6 +7,7 @@
#include <osmocom/core/select.h>
#include <openbsc/rest_octets.h>
+#include <openbsc/common.h>
/** annotations for msgb ownership */
#define __uses
@@ -100,11 +101,11 @@ struct neigh_meas_proc {
enum interface_type {
IFACE_UNKNOWN = 0,
- IFACE_A,
- IFACE_IUCS
+ IFACE_A, /* A-interface == 2G */
+ IFACE_IUCS /* IuCS-interface == UMTS aka 3G */
};
-/* the per subscriber data for lchan */
+/* mobile subscriber data */
struct gsm_subscriber_connection {
struct llist_head entry;
@@ -135,23 +136,35 @@ struct gsm_subscriber_connection {
struct osmo_bsc_sccp_con *sccp_con;
/* back pointers */
- int in_release;
- struct gsm_lchan *lchan;
- struct gsm_lchan *ho_lchan;
- struct gsm_bts *bts;
+ struct gsm_network *network;
/* for assignment handling */
struct osmo_timer_list T10;
struct gsm_lchan *secondary_lchan;
- /* see enum interface_type */
+ /* 2G or 3G? See enum interface_type */
int via_iface;
/* which Iu-CS connection, if any. */
struct {
- uint8_t link_id;
- uint32_t conn_id;
+ struct ue_conn_ctx *ue_ctx;
} iu;
+
+ /* The BSC used to be an integral part of OsmoNITB. In OsmoCSCN, the
+ * BSC and/or RNC is a separate entity, and no back pointers to the bts
+ * and lchan structures are available. To facilitate separation of the
+ * code paths, I'm explicitly excluding the unavailable structures from
+ * the build. Once separated, this split may become unnecessary. */
+#if COMPILING_LIBMSC
+ int in_release;
+ uint16_t lac;
+ struct gsm_encr encr;
+#else
+ struct gsm_bts *bts;
+ struct gsm_lchan *lchan;
+ struct gsm_lchan *ho_lchan;
+#endif
+
};
@@ -308,6 +321,21 @@ struct gsm_network {
/* all active subscriber connections. */
struct llist_head subscr_conns;
+
+ /* if override is nonzero, this timezone data is used for all MM
+ * contexts. */
+ /* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable
+ * BTS|RNC specific timezone overrides for multi-tz networks in
+ * OsmoCSCN, this should be tied to the location area code (LAC). */
+ struct {
+ int override; /* if 0, use system's time zone instead. */
+ int hr; /* hour */
+ int mn; /* minute */
+ int dst; /* daylight savings */
+ } tz;
+
+ /* Periodic location update default value */
+ uint8_t t3212;
};
struct osmo_esme;
@@ -358,10 +386,6 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod
int (*mncc_recv)(struct gsm_network *, struct msgb *));
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
-/* Get reference to a neighbor cell on a given BCCH ARFCN */
-struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
- uint16_t arfcn, uint8_t bsic);
-
enum gsm_bts_type parse_btstype(const char *arg);
const char *btstype2str(enum gsm_bts_type type);
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
@@ -444,7 +468,6 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
-struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
int gsm_bts_model_register(struct gsm_bts_model *model);
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index f8e993566..d4891a988 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -24,6 +24,8 @@
#include <osmocom/gsm/lapdm.h>
#endif
+#include <openbsc/common.h>
+
struct osmo_bsc_data;
struct osmo_bsc_sccp_con;
@@ -100,7 +102,6 @@ struct gsm_abis_mo {
struct gsm_bts *bts;
};
-#define MAX_A5_KEY_LEN (128/8)
#define A38_XOR_MIN_KEY_LEN 12
#define A38_XOR_MAX_KEY_LEN 16
#define A38_COMP128_KEY_LEN 16
@@ -201,11 +202,7 @@ struct gsm_lchan {
uint8_t bs_power;
uint8_t ms_power;
/* Encryption information */
- struct {
- uint8_t alg_id;
- uint8_t key_len;
- uint8_t key[MAX_A5_KEY_LEN];
- } encr;
+ struct gsm_encr encr;
/* AMR bits */
uint8_t mr_ms_lv[7];
@@ -608,14 +605,6 @@ struct gsm_bts {
/* buffers where we put the pre-computed SI */
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
- /* TimeZone hours, mins, and bts specific */
- struct {
- int hr;
- int mn;
- int override;
- int dst;
- } tz;
-
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
union {
struct {
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index 7d6c776bc..88c36e7a9 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -102,7 +102,8 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
unsigned long long id);
struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
const char *imsi);
-int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
+int subscr_update(struct gsm_network *network, struct gsm_subscriber *s,
+ uint16_t lac, int reason);
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi);
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
@@ -113,7 +114,7 @@ char *subscr_name(struct gsm_subscriber *subscr);
int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
void subscr_update_from_db(struct gsm_subscriber *subscr);
void subscr_expire(struct gsm_subscriber_group *sgrp);
-int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts);
+int subscr_update_expire_lu(struct gsm_network *network, struct gsm_subscriber *subscr);
/*
* Paging handling with authentication
diff --git a/openbsc/include/openbsc/iu.h b/openbsc/include/openbsc/iu.h
index 2a759ebe4..3bcc37825 100644
--- a/openbsc/include/openbsc/iu.h
+++ b/openbsc/include/openbsc/iu.h
@@ -3,8 +3,11 @@
struct msgb;
struct gprs_ra_id;
+struct iu_cb_ctx {
+ struct gsm_network *network;
+};
+
struct ue_conn_ctx {
- struct llist_head list;
struct osmo_sua_link *link;
uint32_t conn_id;
};
@@ -15,7 +18,7 @@ typedef int (* iu_recv_cb_t )(struct msgb *msg, struct gprs_ra_id *ra_id,
uint16_t *sai);
int iu_init(void *ctx, const char *listen_addr, uint16_t listen_port,
- iu_recv_cb_t iu_recv_cb);
+ struct gsm_network *network, iu_recv_cb_t iu_recv_cb);
int iu_tx(struct msgb *msg, uint8_t sapi);
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index 8f27b3831..4784132f3 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -142,7 +142,7 @@ struct gsm_subscriber;
struct paging_signal_data {
struct gsm_subscriber *subscr;
- struct gsm_bts *bts;
+ uint16_t lac;
int paging_result;
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 92d2ce274..9c42bb881 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -420,7 +420,7 @@ int main(int argc, char **argv)
}
asn_debug = 0;
- iu_init(tall_bsc_ctx, "127.0.0.2", 14001, gsm0408_gprs_rcvmsg_iu);
+ iu_init(tall_bsc_ctx, "127.0.0.2", 14001, NULL, gsm0408_gprs_rcvmsg_iu);
if (daemonize) {
rc = osmo_daemonize();
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);
diff --git a/openbsc/src/libcommon/common_vty.c b/openbsc/src/libcommon/common_vty.c
index a0674f0f1..4f6f020b3 100644
--- a/openbsc/src/libcommon/common_vty.c
+++ b/openbsc/src/libcommon/common_vty.c
@@ -42,6 +42,7 @@ int bsc_vty_go_parent(struct vty *vty)
vty->node = CONFIG_NODE;
vty->index = NULL;
break;
+#ifdef ROLE_BSC
case BTS_NODE:
vty->node = GSMNET_NODE;
{
@@ -51,6 +52,7 @@ int bsc_vty_go_parent(struct vty *vty)
vty->index_sub = NULL;
}
break;
+#endif
case TRX_NODE:
vty->node = BTS_NODE;
{
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 16035edcc..c852a50f8 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -70,25 +70,6 @@ int gsm_bts_model_register(struct gsm_bts_model *model)
return 0;
}
-/* Get reference to a neighbor cell on a given BCCH ARFCN */
-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) {
- if (neigh->c0->arfcn == arfcn &&
- neigh->bsic == bsic)
- return neigh;
- }
-
- return NULL;
-}
-
const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE+1] = {
{ GSM_BTS_TYPE_UNKNOWN, "unknown" },
{ GSM_BTS_TYPE_BS11, "bs11" },
@@ -228,19 +209,6 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
return 1;
}
-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;
-}
-
int gsm_btsmodel_set_feature(struct gsm_bts_model *bts, enum gsm_bts_features feat)
{
return bitvec_set_bit_pos(&bts->features, feat, 1);
@@ -331,7 +299,7 @@ struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_typ
bts->si_common.chan_desc.att = 1; /* attachment required */
bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
- bts->si_common.chan_desc.t3212 = 5; /* Use 30 min periodic update interval as sane default */
+ bts->si_common.chan_desc.t3212 = net->t3212; /* Use network's current value */
set_radio_link_timeout(&bts->si_common.cell_options, 32);
/* Use RADIO LINK TIMEOUT of 32 seconds */
diff --git a/openbsc/src/libiu/iu.c b/openbsc/src/libiu/iu.c
index c1898d0c6..bb1873566 100644
--- a/openbsc/src/libiu/iu.c
+++ b/openbsc/src/libiu/iu.c
@@ -33,7 +33,6 @@ void *talloc_asn1_ctx;
iu_recv_cb_t global_iu_recv_cb = NULL;
-static LLIST_HEAD(ue_conn_ctx_list);
struct ue_conn_ctx *ue_conn_ctx_alloc(struct osmo_sua_link *link, uint32_t conn_id)
{
@@ -41,16 +40,22 @@ struct ue_conn_ctx *ue_conn_ctx_alloc(struct osmo_sua_link *link, uint32_t conn_
ctx->link = link;
ctx->conn_id = conn_id;
- llist_add(&ctx->list, &ue_conn_ctx_list);
return ctx;
}
-struct ue_conn_ctx *ue_conn_ctx_find(struct osmo_sua_link *link, uint32_t conn_id)
+struct ue_conn_ctx *ue_conn_ctx_find(struct gsm_network *network,
+ struct osmo_sua_link *link,
+ uint32_t conn_id)
{
+ struct gsm_subscriber_connection *gsc;
struct ue_conn_ctx *ctx;
- llist_for_each_entry(ctx, &ue_conn_ctx_list, list) {
+ llist_for_each_entry(gsc, &network->subscr_conns, entry) {
+ if (gsc->via_iface != IFACE_IUCS)
+ continue;
+
+ ctx = gsc->iu.ue_ctx;
if (ctx->link == link && ctx->conn_id == conn_id)
return ctx;
}
@@ -398,6 +403,9 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
struct osmo_prim_hdr *resp = NULL;
int rc;
struct ue_conn_ctx *ue;
+ struct osmo_sua_link *osl = (struct osmo_sua_link*)link;
+ struct iu_cb_ctx *iu_ctx = (struct iu_cb_ctx*)osmo_sua_link_get_user_priv(osl);
+ struct gsm_network *network = iu_ctx->network;
printf("sccp_sap_up(%s)\n", osmo_scu_prim_name(oph));
@@ -424,7 +432,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
/* indication of disconnect */
printf("N-DISCONNECT.ind(%u)\n", prim->u.disconnect.conn_id);
- ue = ue_conn_ctx_find(link, prim->u.disconnect.conn_id);
+ ue = ue_conn_ctx_find(network, link, prim->u.disconnect.conn_id);
rc = ranap_cn_rx_co(cn_ranap_handle_co, ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DATA, PRIM_OP_INDICATION):
@@ -432,7 +440,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
printf("N-DATA.ind(%u, %s)\n", prim->u.data.conn_id,
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
/* resolve UE context */
- ue = ue_conn_ctx_find(link, prim->u.data.conn_id);
+ ue = ue_conn_ctx_find(network, link, prim->u.data.conn_id);
rc = ranap_cn_rx_co(cn_ranap_handle_co, ue, msgb_l2(oph->msg), msgb_l2len(oph->msg));
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
@@ -451,13 +459,18 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *link)
}
int iu_init(void *ctx, const char *listen_addr, uint16_t listen_port,
- iu_recv_cb_t iu_recv_cb)
+ struct gsm_network *network, iu_recv_cb_t iu_recv_cb)
{
+ struct iu_cb_ctx *iu_ctx;
struct osmo_sua_user *user;
talloc_asn1_ctx = talloc_named_const(ctx, 1, "asn1");
+
+ iu_ctx = talloc_zero(ctx, struct iu_cb_ctx);
+ iu_ctx->network = network;
+
global_iu_recv_cb = iu_recv_cb;
osmo_sua_set_log_area(DSUA);
- user = osmo_sua_user_create(ctx, sccp_sap_up, ctx);
+ user = osmo_sua_user_create(ctx, sccp_sap_up, iu_ctx);
return osmo_sua_server_listen(user, listen_addr, listen_port);
}
diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am
index b9efee597..ffa0c8623 100644
--- a/openbsc/src/libmsc/Makefile.am
+++ b/openbsc/src/libmsc/Makefile.am
@@ -1,4 +1,5 @@
-AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) \
+ -DCOMPILING_LIBMSC=1
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBSMPP34_CFLAGS)
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index ccf30eb6e..17c53e044 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -65,11 +65,13 @@
#include <assert.h>
+/* These debug statements were removed during the BSC/MSC split. It may make
+ * sense to replace them with debug statements that do not access BTS data. */
+#define BEFORE_MSCSPLIT 0
+
void *tall_locop_ctx;
void *tall_authciphop_ctx;
-static int tch_rtp_signal(struct gsm_lchan *lchan, int signal);
-
static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn);
static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
uint8_t pdisc, uint8_t msg_type);
@@ -82,29 +84,6 @@ struct gsm_lai {
uint16_t lac;
};
-static int apply_codec_restrictions(struct gsm_bts *bts,
- struct gsm_mncc_bearer_cap *bcap)
-{
- int i, j;
-
- /* remove unsupported speech versions from list */
- for (i = 0, j = 0; bcap->speech_ver[i] >= 0; i++) {
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_FR)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_FR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_EFR && bts->codec.efr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_EFR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_F && bts->codec.amr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_F;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_HR && bts->codec.hr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_HR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_H && bts->codec.amr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_H;
- }
- bcap->speech_ver[j] = -1;
-
- return 0;
-}
-
static uint32_t new_callref = 0x80000001;
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
@@ -123,26 +102,6 @@ static int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection
gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
}
-
- if (conn && conn->lchan) {
- struct e1inp_sign_link *sign_link =
- conn->lchan->ts->trx->rsl_link;
-
- if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC)
- DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) "
- "Sending '%s' to MS.\n",
- sign_link->trx->bts->nr,
- sign_link->trx->nr, conn->lchan->ts->nr,
- gh->proto_discr & 0xf0,
- gsm48_cc_msg_name(gh->msg_type));
- else
- DEBUGP(DCC, "(bts %d trx %d ts %d pd %02x) "
- "Sending 0x%02x to MS.\n",
- sign_link->trx->bts->nr,
- sign_link->trx->nr, conn->lchan->ts->nr,
- gh->proto_discr, gh->msg_type);
- }
-
return gsm0808_submit_dtap(conn, msg, 0, 0);
}
@@ -182,7 +141,7 @@ void allocate_security_operation(struct gsm_subscriber_connection *conn)
int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq,
gsm_cbfn *cb, void *cb_data)
{
- struct gsm_network *net = conn->bts->network;
+ struct gsm_network *net = conn->network;
struct gsm_subscriber *subscr = conn->subscr;
struct gsm_security_operation *op;
struct gsm_auth_tuple atuple;
@@ -195,7 +154,7 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq,
*/
if (!net->a5_encryption) {
status = GSM_SECURITY_NOAVAIL;
- } else if (conn->lchan->encr.alg_id > RSL_ENC_ALG_A5(0)) {
+ } else if (conn->encr.alg_id > RSL_ENC_ALG_A5(0)) {
DEBUGP(DMM, "Requesting to secure an already secure channel");
status = GSM_SECURITY_ALREADY;
} else if (!ms_cm2_a5n_support(subscr->equipment.classmark2,
@@ -298,7 +257,7 @@ static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn)
static int finish_lu(struct gsm_subscriber_connection *conn)
{
int rc = 0;
- int avoid_tmsi = conn->bts->network->avoid_tmsi;
+ int avoid_tmsi = conn->network->avoid_tmsi;
/* We're all good */
if (avoid_tmsi) {
@@ -309,7 +268,7 @@ static int finish_lu(struct gsm_subscriber_connection *conn)
}
rc = gsm0408_loc_upd_acc(conn);
- if (conn->bts->network->send_mm_info) {
+ if (conn->network->send_mm_info) {
/* send MM INFO with network name */
rc = gsm48_tx_mm_info(conn);
}
@@ -317,7 +276,7 @@ static int finish_lu(struct gsm_subscriber_connection *conn)
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
- subscr_update(conn->subscr, conn->bts,
+ subscr_update(conn->network, conn->subscr, conn->lac,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
/*
@@ -406,7 +365,7 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus
* we have a subscriber connection.
*/
restart:
- llist_for_each_entry_safe(trans, temp, &conn->bts->network->trans_list, entry) {
+ llist_for_each_entry_safe(trans, temp, &conn->network->trans_list, entry) {
if (trans->conn == conn) {
trans_free(trans);
goto restart;
@@ -431,10 +390,9 @@ void gsm0408_clear_all_trans(struct gsm_network *net, int protocol)
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
{
- struct gsm_bts *bts = conn->bts;
struct msgb *msg;
- osmo_counter_inc(bts->network->stats.loc_upd_resp.reject);
+ osmo_counter_inc(conn->network->stats.loc_upd_resp.reject);
msg = gsm48_create_loc_upd_rej(cause);
if (!msg) {
@@ -442,9 +400,14 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
return -1;
}
+#if BEFORE_MSCSPLIT
LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT "
"LAC=%u BTS=%u\n", subscr_name(conn->subscr),
bts->location_area_code, bts->nr);
+#else
+ LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n",
+ subscr_name(conn->subscr));
+#endif
return gsm48_conn_sendmsg(msg, conn, NULL);
}
@@ -452,7 +415,6 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
{
- struct gsm_bts *bts = conn->bts;
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 LOC UPD ACC");
struct gsm48_hdr *gh;
struct gsm48_loc_area_id *lai;
@@ -463,8 +425,8 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
- gsm48_generate_lai(lai, bts->network->country_code,
- bts->network->network_code, bts->location_area_code);
+ gsm48_generate_lai(lai, conn->network->country_code,
+ conn->network->network_code, conn->lac);
if (conn->subscr->tmsi == GSM_RESERVED_TMSI) {
uint8_t mi[10];
@@ -479,7 +441,7 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
- osmo_counter_inc(bts->network->stats.loc_upd_resp.accept);
+ osmo_counter_inc(conn->network->stats.loc_upd_resp.accept);
return gsm48_conn_sendmsg(msg, conn, NULL);
}
@@ -503,9 +465,7 @@ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id
static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm_lchan *lchan = msg->lchan;
- struct gsm_bts *bts = lchan->ts->trx->bts;
- struct gsm_network *net = bts->network;
+ struct gsm_network *net = conn->network;
uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
char mi_string[GSM48_MI_SIZE];
@@ -526,7 +486,7 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms
net->subscr_group, mi_string);
}
if (!conn->subscr && conn->loc_operation) {
- gsm0408_loc_upd_rej(conn, bts->network->reject_cause);
+ gsm0408_loc_upd_rej(conn, net->reject_cause);
release_loc_updating_req(conn, 1);
return 0;
}
@@ -553,11 +513,9 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms
static void loc_upd_rej_cb(void *data)
{
struct gsm_subscriber_connection *conn = data;
- struct gsm_lchan *lchan = conn->lchan;
- struct gsm_bts *bts = lchan->ts->trx->bts;
LOGP(DMM, LOGL_DEBUG, "Location Updating Request procedure timedout.\n");
- gsm0408_loc_upd_rej(conn, bts->network->reject_cause);
+ gsm0408_loc_upd_rej(conn, conn->network->reject_cause);
release_loc_updating_req(conn, 1);
}
@@ -581,7 +539,6 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_loc_upd_req *lu;
struct gsm_subscriber *subscr = NULL;
- struct gsm_bts *bts = conn->bts;
uint8_t mi_type;
char mi_string[GSM48_MI_SIZE];
@@ -598,13 +555,13 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
switch (lu->type) {
case GSM48_LUPD_NORMAL:
- osmo_counter_inc(bts->network->stats.loc_upd_type.normal);
+ osmo_counter_inc(conn->network->stats.loc_upd_type.normal);
break;
case GSM48_LUPD_IMSI_ATT:
- osmo_counter_inc(bts->network->stats.loc_upd_type.attach);
+ osmo_counter_inc(conn->network->stats.loc_upd_type.attach);
break;
case GSM48_LUPD_PERIODIC:
- osmo_counter_inc(bts->network->stats.loc_upd_type.periodic);
+ osmo_counter_inc(conn->network->stats.loc_upd_type.periodic);
break;
}
@@ -631,13 +588,13 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
conn->loc_operation->waiting_for_imei = 1;
/* look up subscriber based on IMSI, create if not found */
- subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string);
- if (!subscr && bts->network->create_subscriber) {
+ subscr = subscr_get_by_imsi(conn->network->subscr_group, mi_string);
+ if (!subscr && conn->network->create_subscriber) {
subscr = subscr_create_subscriber(
- bts->network->subscr_group, mi_string);
+ conn->network->subscr_group, mi_string);
}
if (!subscr) {
- gsm0408_loc_upd_rej(conn, bts->network->reject_cause);
+ gsm0408_loc_upd_rej(conn, conn->network->reject_cause);
release_loc_updating_req(conn, 0);
return 0;
}
@@ -645,7 +602,7 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
case GSM_MI_TYPE_TMSI:
DEBUGPC(DMM, "\n");
/* look up the subscriber based on TMSI, request IMSI if it fails */
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ subscr = subscr_get_by_tmsi(conn->network->subscr_group,
tmsi_from_string(mi_string));
if (!subscr) {
/* send IDENTITY REQUEST message to get IMSI */
@@ -700,8 +657,7 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
{
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 MM INF");
struct gsm48_hdr *gh;
- struct gsm_network *net = conn->bts->network;
- struct gsm_bts *bts = conn->bts;
+ struct gsm_network *net = conn->network;
uint8_t *ptr8;
int name_len, name_pad;
@@ -787,23 +743,24 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
ptr8[5] = bcdify(gmt_time->tm_min);
ptr8[6] = bcdify(gmt_time->tm_sec);
- if (bts->tz.override) {
+ // MSCSPLIT bts->tz move to BSC?
+ if (net->tz.override) {
/* Convert tz.hr and tz.mn to units */
- if (bts->tz.hr < 0) {
- tzunits = ((bts->tz.hr/-1)*4);
- tzunits = tzunits + (bts->tz.mn/15);
+ if (net->tz.hr < 0) {
+ tzunits = ((net->tz.hr/-1)*4);
+ tzunits = tzunits + (net->tz.mn/15);
ptr8[7] = bcdify(tzunits);
/* Set negative time */
ptr8[7] |= 0x08;
}
else {
- tzunits = bts->tz.hr*4;
- tzunits = tzunits + (bts->tz.mn/15);
+ tzunits = net->tz.hr*4;
+ tzunits = tzunits + (net->tz.mn/15);
ptr8[7] = bcdify(tzunits);
}
/* Convert DST value */
- if (bts->tz.dst >= 0 && bts->tz.dst <= 2)
- dst = bts->tz.dst;
+ if (net->tz.dst >= 0 && net->tz.dst <= 2)
+ dst = net->tz.dst;
}
else {
/* Need to get GSM offset and convert into 15 min units */
@@ -879,7 +836,7 @@ static void implit_attach(struct gsm_subscriber_connection *conn)
if (conn->subscr->lac != GSM_LAC_RESERVED_DETACHED)
return;
- subscr_update(conn->subscr, conn->bts,
+ subscr_update(conn->network, conn->subscr, conn->lac,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
}
@@ -932,7 +889,7 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
uint8_t mi_type;
char mi_string[GSM48_MI_SIZE];
- struct gsm_bts *bts = conn->bts;
+ struct gsm_network *network = conn->network;
struct gsm_subscriber *subscr;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_service_request *req =
@@ -963,13 +920,13 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n",
req->cm_service_type, gsm48_mi_type_name(mi_type),
mi_string);
- subscr = subscr_get_by_imsi(bts->network->subscr_group,
+ subscr = subscr_get_by_imsi(network->subscr_group,
mi_string);
} else if (mi_type == GSM_MI_TYPE_TMSI) {
DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n",
req->cm_service_type, gsm48_mi_type_name(mi_type),
mi_string);
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ subscr = subscr_get_by_tmsi(network->subscr_group,
tmsi_from_string(mi_string));
} else {
DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
@@ -979,8 +936,11 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
+#if BEFORE_MSCSPLIT
+ /* see mail on openbsc@ 9 Feb 2016 22:30:15 +0100 */
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
+#endif
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
@@ -1010,7 +970,7 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
- struct gsm_bts *bts = conn->bts;
+ struct gsm_network *network = conn->network;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_imsi_detach_ind *idi =
(struct gsm48_imsi_detach_ind *) gh->data;
@@ -1022,17 +982,17 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s
DEBUGP(DMM, "IMSI DETACH INDICATION: MI(%s)=%s",
gsm48_mi_type_name(mi_type), mi_string);
- osmo_counter_inc(bts->network->stats.loc_upd_type.detach);
+ osmo_counter_inc(network->stats.loc_upd_type.detach);
switch (mi_type) {
case GSM_MI_TYPE_TMSI:
DEBUGPC(DMM, "\n");
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ subscr = subscr_get_by_tmsi(network->subscr_group,
tmsi_from_string(mi_string));
break;
case GSM_MI_TYPE_IMSI:
DEBUGPC(DMM, "\n");
- subscr = subscr_get_by_imsi(bts->network->subscr_group,
+ subscr = subscr_get_by_imsi(network->subscr_group,
mi_string);
break;
case GSM_MI_TYPE_IMEI:
@@ -1046,7 +1006,7 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s
}
if (subscr) {
- subscr_update(subscr, bts,
+ subscr_update(network, subscr, conn->lac,
GSM_SUBSCRIBER_UPDATE_DETACHED);
DEBUGP(DMM, "Subscriber: %s\n", subscr_name(subscr));
@@ -1078,7 +1038,7 @@ static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct
{
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_auth_resp *ar = (struct gsm48_auth_resp*) gh->data;
- struct gsm_network *net = conn->bts->network;
+ struct gsm_network *net = conn->network;
DEBUGP(DMM, "MM AUTHENTICATION RESPONSE (sres = %s): ",
osmo_hexdump(ar->sres, 4));
@@ -1159,7 +1119,6 @@ static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *m
/* Receive a PAGING RESPONSE message from the MS */
static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
- struct gsm_bts *bts = conn->bts;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_pag_resp *resp;
uint8_t *classmark2_lv = gh->data + 1;
@@ -1176,11 +1135,11 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
switch (mi_type) {
case GSM_MI_TYPE_TMSI:
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ subscr = subscr_get_by_tmsi(conn->network->subscr_group,
tmsi_from_string(mi_string));
break;
case GSM_MI_TYPE_IMSI:
- subscr = subscr_get_by_imsi(bts->network->subscr_group,
+ subscr = subscr_get_by_imsi(conn->network->subscr_group,
mi_string);
break;
}
@@ -1328,6 +1287,7 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
struct msgb *msg;
unsigned char *data;
+#if BEFORE_MSCSPLIT
if (trans)
if (trans->conn && trans->conn->lchan)
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
@@ -1345,6 +1305,7 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
else
DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) "
"Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
+#endif
mncc->msg_type = msg_type;
@@ -1388,8 +1349,10 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
}
if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL);
+#if BEFORE_MSCSPLIT
if (trans->conn)
trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref);
+#endif
}
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
@@ -1436,6 +1399,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable);
+#if BEFORE_MSCSPLIT
/* handle audio path for handover */
static int switch_for_handover(struct gsm_lchan *old_lchan,
struct gsm_lchan *new_lchan)
@@ -1503,77 +1467,6 @@ static void maybe_switch_for_handover(struct gsm_lchan *lchan)
switch_for_handover(old_lchan, lchan);
}
-/* some other part of the code sends us a signal */
-static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct gsm_lchan *lchan = signal_data;
- int rc;
- struct gsm_network *net;
- struct gsm_trans *trans;
-
- if (subsys != SS_ABISIP)
- return 0;
-
- /* RTP bridge handling */
- if (lchan->conn && lchan->conn->mncc_rtp_bridge)
- return tch_rtp_signal(lchan, signal);
-
- /* in case we use direct BTS-to-BTS RTP */
- if (ipacc_rtp_direct)
- return 0;
-
- switch (signal) {
- case S_ABISIP_CRCX_ACK:
- /* in case we don't use direct BTS-to-BTS RTP */
- /* the BTS has successfully bound a TCH to a local ip/port,
- * which means we can connect our UDP socket to it */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
- lchan->abis_ip.rtp_socket = rtp_socket_create();
- if (!lchan->abis_ip.rtp_socket)
- return -EIO;
-
- rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
- lchan->abis_ip.bound_ip,
- lchan->abis_ip.bound_port);
- if (rc < 0)
- return -EIO;
-
- /* check if any transactions on this lchan still have
- * a tch_recv_mncc request pending */
- net = lchan->ts->trx->bts->network;
- llist_for_each_entry(trans, &net->trans_list, entry) {
- if (trans->conn && trans->conn->lchan == lchan && trans->tch_recv) {
- DEBUGP(DCC, "pending tch_recv_mncc request\n");
- tch_recv_mncc(net, trans->callref, 1);
- }
- }
-
- /*
- * TODO: this appears to be too early? Why not until after
- * the handover detect or the handover complete?
- *
- * Do we have a handover pending for this new lchan? In that
- * case re-route the audio from the old channel to the new one.
- */
- maybe_switch_for_handover(lchan);
- break;
- case S_ABISIP_DLCX_IND:
- /* the BTS tells us a RTP stream has been disconnected */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
- break;
- }
-
- return 0;
-}
/* map two ipaccess RTP streams onto each other */
static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
@@ -1641,6 +1534,7 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
return 0;
}
+#endif
/* bridge channels of two transactions */
static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge)
@@ -1657,13 +1551,19 @@ static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge)
/* Which subscriber do we want to track trans1 or trans2? */
log_set_context(BSC_CTX_SUBSCR, trans1->subscr);
+#if BEFORE_MSCSPLIT
/* through-connect channel */
return tch_map(trans1->conn->lchan, trans2->conn->lchan);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
/* enable receive of channels to MNCC upqueue */
static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
{
+#if BEFORE_MSCSPLIT
struct gsm_trans *trans;
struct gsm_lchan *lchan;
struct gsm_bts *bts;
@@ -1732,6 +1632,10 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
}
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
@@ -1848,7 +1752,11 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
memset(&setup, 0, sizeof(struct gsm_mncc));
setup.callref = trans->callref;
+#if BEFORE_MSCSPLIT
setup.lchan_type = trans->conn->lchan->type;
+#else
+ setup.lchan_type = GSM_LCHAN_NONE;
+#endif
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
/* emergency setup is identified by msg_type */
if (msg_type == GSM48_MT_CC_EMERG_SETUP)
@@ -1866,7 +1774,6 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
setup.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&setup.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &setup.bearer_cap);
}
/* facility */
if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
@@ -2006,7 +1913,11 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
memset(&call_conf, 0, sizeof(struct gsm_mncc));
call_conf.callref = trans->callref;
+#if BEFORE_MSCSPLIT
call_conf.lchan_type = trans->conn->lchan->type;
+#else
+ call_conf.lchan_type = GSM_LCHAN_NONE;
+#endif
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
#if 0
/* repeat */
@@ -2020,7 +1931,6 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
call_conf.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&call_conf.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &call_conf.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
@@ -2713,7 +2623,6 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
@@ -2756,7 +2665,6 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_ACTIVE);
@@ -2797,7 +2705,6 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= GSM48_IE_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
@@ -2902,6 +2809,7 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
{
+#if BEFORE_MSCSPLIT
struct gsm_mncc *mode = arg;
struct gsm_lchan *lchan = trans->conn->lchan;
@@ -2917,8 +2825,14 @@ static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
return gsm0808_assign_req(trans->conn, mode->lchan_mode,
trans->conn->lchan->type != GSM_LCHAN_TCH_H);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
+
}
+#if BEFORE_MSCSPLIT
static void mncc_recv_rtp(struct gsm_network *net, uint32_t callref,
int cmd, uint32_t addr, uint16_t port, uint32_t payload_type,
uint32_t payload_msg_type)
@@ -2975,9 +2889,11 @@ static void mncc_recv_rtp_err(struct gsm_network *net, uint32_t callref, int cmd
{
return mncc_recv_rtp(net, callref, cmd, 0, 0, 0, 0);
}
+#endif
static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
{
+#if BEFORE_MSCSPLIT
struct gsm_bts *bts;
struct gsm_lchan *lchan;
struct gsm_trans *trans;
@@ -3027,10 +2943,15 @@ static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
mncc_recv_rtp_sock(trans->net, trans, MNCC_RTP_CREATE);
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
static int tch_rtp_connect(struct gsm_network *net, void *arg)
{
+#if BEFORE_MSCSPLIT
struct gsm_lchan *lchan;
struct gsm_trans *trans;
struct gsm_mncc_rtp *rtp = arg;
@@ -3064,8 +2985,13 @@ static int tch_rtp_connect(struct gsm_network *net, void *arg)
*/
trans->conn->mncc_rtp_connect_pending = 1;
return rsl_ipacc_mdcx(lchan, rtp->ip, rtp->port, 0);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
+#if BEFORE_MSCSPLIT
static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
{
struct gsm_network *net;
@@ -3113,6 +3039,7 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
return 0;
}
+#endif
static struct downstate {
@@ -3182,7 +3109,6 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
int i, rc = 0;
struct gsm_trans *trans = NULL, *transt;
struct gsm_subscriber_connection *conn = NULL;
- struct gsm_bts *bts = NULL;
struct gsm_mncc *data = arg, rel;
DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type));
@@ -3217,6 +3143,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n");
return 0;
}
+#if BEFORE_MSCSPLIT
if (!trans->conn->lchan) {
LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without lchan\n");
return 0;
@@ -3246,6 +3173,10 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type);
}
return -EINVAL;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
memset(&rel, 0, sizeof(struct gsm_mncc));
@@ -3387,6 +3318,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
return rc;
}
+#if BEFORE_MSCSPLIT
DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
"Received '%s' from MNCC in state %d (%s)\n",
conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr,
@@ -3394,6 +3326,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
(trans->conn->subscr)?(trans->conn->subscr->extension):"-",
get_mncc_name(msg_type), trans->cc.state,
gsm48_cc_state_name(trans->cc.state));
+#endif
/* Find function for current state and message */
for (i = 0; i < DOWNSLLEN; i++)
@@ -3481,19 +3414,21 @@ static int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *m
/* Find transaction */
trans = trans_find_by_id(conn, GSM48_PDISC_CC, transaction_id);
+#if BEFORE_MSCSPLIT
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
"Received '%s' from MS in state %d (%s)\n",
conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr,
transaction_id, (conn->subscr)?(conn->subscr->extension):"-",
gsm48_cc_msg_name(msg_type), trans?(trans->cc.state):0,
gsm48_cc_state_name(trans?(trans->cc.state):0));
+#endif
/* Create transaction */
if (!trans) {
DEBUGP(DCC, "Unknown transaction ID %x, "
"creating new trans.\n", transaction_id);
/* Create transaction */
- trans = trans_alloc(conn->bts->network, conn->subscr,
+ trans = trans_alloc(conn->network, conn->subscr,
GSM48_PDISC_CC,
transaction_id, new_callref++);
if (!trans) {
@@ -3601,11 +3536,3 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
return rc;
}
-/*
- * This will be ran by the linker when loading the DSO. We use it to
- * do system initialization, e.g. registration of signal handlers.
- */
-static __attribute__((constructor)) void on_dso_load_0408(void)
-{
- osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, NULL);
-}
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index a9ea17684..4b6c87556 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -304,7 +304,7 @@ try_local:
#endif
/* determine gsms->receiver based on dialled number */
- gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group,
+ gsms->receiver = subscr_get_by_extension(conn->network->subscr_group,
gsms->dst.addr);
if (!gsms->receiver) {
#ifdef BUILD_SMPP
@@ -322,7 +322,7 @@ try_local:
}
#else
rc = 1; /* cause 1: unknown subscriber */
- osmo_counter_inc(conn->bts->network->stats.sms.no_receiver);
+ osmo_counter_inc(conn->network->stats.sms.no_receiver);
#endif
return rc;
}
@@ -363,7 +363,7 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m
uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
int rc = 0;
- osmo_counter_inc(conn->bts->network->stats.sms.submitted);
+ osmo_counter_inc(conn->network->stats.sms.submitted);
gsms = sms_alloc();
if (!gsms)
@@ -605,7 +605,7 @@ static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans,
static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans,
struct gsm411_rp_hdr *rph)
{
- struct gsm_network *net = trans->conn->bts->network;
+ struct gsm_network *net = trans->conn->network;
struct gsm_sms *sms = trans->sms.sms;
uint8_t cause_len = rph->data[0];
uint8_t cause = rph->data[1];
@@ -805,7 +805,7 @@ int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn,
if (!trans) {
DEBUGP(DLSMS, " -> (new transaction)\n");
- trans = trans_alloc(conn->bts->network, conn->subscr,
+ trans = trans_alloc(conn->network, conn->subscr,
GSM48_PDISC_SMS,
transaction_id, new_callref++);
if (!trans) {
@@ -867,7 +867,7 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
int rc;
transaction_id =
- trans_assign_trans_id(conn->bts->network, conn->subscr,
+ trans_assign_trans_id(conn->network, conn->subscr,
GSM48_PDISC_SMS, 0);
if (transaction_id == -1) {
LOGP(DLSMS, LOGL_ERROR, "No available transaction ids\n");
@@ -880,7 +880,7 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
DEBUGP(DLSMS, "gsm411_send_sms()\n");
/* FIXME: allocate transaction with message reference */
- trans = trans_alloc(conn->bts->network, conn->subscr,
+ trans = trans_alloc(conn->network, conn->subscr,
GSM48_PDISC_SMS,
transaction_id, new_callref++);
if (!trans) {
@@ -932,7 +932,7 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
DEBUGP(DLSMS, "TX: SMS DELIVER\n");
- osmo_counter_inc(conn->bts->network->stats.sms.delivered);
+ osmo_counter_inc(conn->network->stats.sms.delivered);
db_sms_inc_deliver_attempts(trans->sms.sms);
return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
@@ -1022,7 +1022,7 @@ void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn)
struct gsm_network *net;
struct gsm_trans *trans, *tmp;
- net = conn->bts->network;
+ net = conn->network;
llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) {
struct gsm_sms *sms;
diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c
index 57c10cf7e..9342a2972 100644
--- a/openbsc/src/libmsc/gsm_subscriber.c
+++ b/openbsc/src/libmsc/gsm_subscriber.c
@@ -94,7 +94,7 @@ static int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
/* Inform parts of the system we don't know */
sig_data.subscr = subscr;
- sig_data.bts = conn ? conn->bts : NULL;
+ sig_data.lac = conn ? conn->lac : 0;
sig_data.conn = conn;
sig_data.paging_result = event;
osmo_signal_dispatch(
@@ -268,7 +268,7 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
return get_subscriber(sgrp, GSM_SUBSCRIBER_ID, buf);
}
-int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts)
+int subscr_update_expire_lu(struct gsm_network *network, struct gsm_subscriber *s)
{
int rc;
@@ -279,27 +279,27 @@ int subscr_update_expire_lu(struct gsm_subscriber *s, struct gsm_bts *bts)
* Timeout is twice the t3212 value plus one minute */
/* Is expiration handling enabled? */
- if (bts->si_common.chan_desc.t3212 == 0)
+ if (network->t3212 == 0)
s->expire_lu = GSM_SUBSCRIBER_NO_EXPIRATION;
else
- s->expire_lu = time(NULL) +
- (bts->si_common.chan_desc.t3212 * 60 * 6 * 2) + 60;
+ s->expire_lu = time(NULL) + (network->t3212 * 60 * 6 * 2) + 60;
rc = db_sync_subscriber(s);
db_subscriber_update(s);
return rc;
}
-int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
+int subscr_update(struct gsm_network *network, struct gsm_subscriber *s,
+ uint16_t lac, int reason)
{
int rc;
/* FIXME: Migrate pending requests from one BSC to another */
switch (reason) {
case GSM_SUBSCRIBER_UPDATE_ATTACHED:
- s->group = bts->network->subscr_group;
+ s->group = network->subscr_group;
/* Indicate "attached to LAC" */
- s->lac = bts->location_area_code;
+ s->lac = lac;
LOGP(DMM, LOGL_INFO, "Subscriber %s ATTACHED LAC=%u\n",
subscr_name(s), s->lac);
@@ -308,12 +308,12 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason)
* The below will set a new expire_lu but as a side-effect
* the new lac will be saved in the database.
*/
- rc = subscr_update_expire_lu(s, bts);
+ rc = subscr_update_expire_lu(network, s);
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_ATTACHED, s);
break;
case GSM_SUBSCRIBER_UPDATE_DETACHED:
/* Only detach if we are currently in this area */
- if (bts->location_area_code == s->lac)
+ if (lac == s->lac)
s->lac = GSM_LAC_RESERVED_DETACHED;
LOGP(DMM, LOGL_INFO, "Subscriber %s DETACHED\n", subscr_name(s));
rc = db_sync_subscriber(s);
@@ -352,7 +352,7 @@ static void subscr_expire_callback(void *data, long long unsigned int id)
if (conn && conn->expire_timer_stopped) {
LOGP(DMM, LOGL_DEBUG, "Not expiring subscriber %s (ID %llu)\n",
subscr_name(s), id);
- subscr_update_expire_lu(s, conn->bts);
+ subscr_update_expire_lu(conn->network, s);
subscr_put(s);
return;
}
diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c
index 77df6fba3..d67035b40 100644
--- a/openbsc/src/libmsc/mncc_builtin.c
+++ b/openbsc/src/libmsc/mncc_builtin.c
@@ -292,11 +292,16 @@ static int mncc_rcv_data(struct gsm_call *call, int msg_type,
return -EIO;
}
+#if BEFORE_MSCSPLIT
/* RTP socket of remote end has meanwhile died */
if (!remote_trans->conn->lchan->abis_ip.rtp_socket)
return -EIO;
return rtp_send_frame(remote_trans->conn->lchan->abis_ip.rtp_socket, dfr);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 0331de552..7f9dabb1b 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -169,7 +169,7 @@ void msc_release_connection(struct gsm_subscriber_connection *conn)
* to restarting the timer. Set the new expiration time.
*/
if (conn->expire_timer_stopped)
- subscr_update_expire_lu(conn->subscr, conn->bts);
+ subscr_update_expire_lu(conn->network, conn->subscr);
conn->in_release = 1;
gsm0808_clear(conn);
diff --git a/openbsc/src/libmsc/rrlp.c b/openbsc/src/libmsc/rrlp.c
index 161456a06..e695daac7 100644
--- a/openbsc/src/libmsc/rrlp.c
+++ b/openbsc/src/libmsc/rrlp.c
@@ -40,7 +40,7 @@ static const uint8_t ass_pref_pos_req[] = { 0x40, 0x03, 0x79, 0x50 };
static int send_rrlp_req(struct gsm_subscriber_connection *conn)
{
- struct gsm_network *net = conn->bts->network;
+ struct gsm_network *net = conn->network;
const uint8_t *req;
switch (net->rrlp.mode) {
diff --git a/openbsc/src/libmsc/silent_call.c b/openbsc/src/libmsc/silent_call.c
index e9ece1835..26be5a7e2 100644
--- a/openbsc/src/libmsc/silent_call.c
+++ b/openbsc/src/libmsc/silent_call.c
@@ -52,8 +52,10 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event,
switch (event) {
case GSM_PAGING_SUCCEEDED:
+#if BEFORE_MSCSPLIT
DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n",
conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
conn->silent_call = 1;
/* increment lchan reference count */
osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata);
@@ -137,8 +139,10 @@ int gsm_silent_call_stop(struct gsm_subscriber *subscr)
if (!conn->silent_call)
return -EINVAL;
+#if BEFORE_MSCSPLIT
DEBUGPC(DLSMS, "Stopping silent call using Timeslot %u on ARFCN %u\n",
conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
conn->silent_call = 0;
msc_release_connection(conn);
diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c
index a75036253..dba4bed17 100644
--- a/openbsc/src/libmsc/transaction.c
+++ b/openbsc/src/libmsc/transaction.c
@@ -37,7 +37,7 @@ struct gsm_trans *trans_find_by_id(struct gsm_subscriber_connection *conn,
uint8_t proto, uint8_t trans_id)
{
struct gsm_trans *trans;
- struct gsm_network *net = conn->bts->network;
+ struct gsm_network *net = conn->network;
struct gsm_subscriber *subscr = conn->subscr;
llist_for_each_entry(trans, &net->trans_list, entry) {
@@ -155,7 +155,7 @@ int trans_has_conn(const struct gsm_subscriber_connection *conn)
{
struct gsm_trans *trans;
- llist_for_each_entry(trans, &conn->bts->network->trans_list, entry)
+ llist_for_each_entry(trans, &conn->network->trans_list, entry)
if (trans->conn == conn)
return 1;
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index f49c53a08..966c920cc 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -605,6 +605,7 @@ DEFUN(ena_subscr_handover,
SUBSCR_HELP "Handover the active connection\n"
"Number of the BTS to handover to\n")
{
+#if BEFORE_MSCSPLIT
int ret;
struct gsm_subscriber_connection *conn;
struct gsm_bts *bts;
@@ -648,6 +649,10 @@ DEFUN(ena_subscr_handover,
subscr_put(subscr);
return CMD_SUCCESS;
+#else
+ vty_out(vty, "%% Not implemented!%s", VTY_NEWLINE);
+ return -1;
+#endif
}
#define A3A8_ALG_TYPES "(none|xor|comp128v1)"
@@ -762,6 +767,7 @@ DEFUN(subscriber_update,
static int scall_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
+#if BEFORE_MSCSPLIT
struct scall_signal_data *sigdata = signal_data;
struct vty *vty = sigdata->data;
@@ -776,6 +782,10 @@ static int scall_cbfn(unsigned int subsys, unsigned int signal,
break;
}
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
DEFUN(show_stats,
diff --git a/openbsc/src/osmo-cscn/cscn_main.c b/openbsc/src/osmo-cscn/cscn_main.c
index ca1c48f48..784ce65b5 100644
--- a/openbsc/src/osmo-cscn/cscn_main.c
+++ b/openbsc/src/osmo-cscn/cscn_main.c
@@ -315,7 +315,7 @@ int main(int argc, char **argv)
#ifdef BUILD_SMPP
smpp_openbsc_set_net(bsc_gsmnet);
#endif
- bsc_api_init(bsc_gsmnet, msc_bsc_api());
+ bsc_api_init(bsc_gsmnet, msc_bsc_api()); // pobably not.
bsc_gsmnet->ctrl = bsc_controlif_setup(bsc_gsmnet, OSMO_CTRL_PORT_NITB_BSC);
if (!bsc_gsmnet->ctrl) {
@@ -381,7 +381,7 @@ int main(int argc, char **argv)
/* TODO: implement A-Interface and remove above legacy stuff. */
/* Set up Iu-CS */
- iu_init(tall_bsc_ctx, "127.0.0.1", 14001, rcvmsg_iu_cs);
+ iu_init(tall_bsc_ctx, "127.0.0.1", 14001, bsc_gsmnet, rcvmsg_iu_cs);
if (daemonize) {
rc = osmo_daemonize();
diff --git a/openbsc/src/osmo-cscn/iu_cs.c b/openbsc/src/osmo-cscn/iu_cs.c
index 7928a7f69..82ce0cf5e 100644
--- a/openbsc/src/osmo-cscn/iu_cs.c
+++ b/openbsc/src/osmo-cscn/iu_cs.c
@@ -12,46 +12,50 @@
/* For A-interface see libbsc/bsc_api.c subscr_con_allocate() */
struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *network,
- uint8_t link_id,
- uint32_t conn_id)
+ struct ue_conn_ctx *ue)
{
struct gsm_subscriber_connection *conn;
- DEBUGP(DIUCS, "Allocating IuCS subscriber conn: link_id %" PRIx8 ", conn_id %" PRIx32 "\n",
- link_id, conn_id);
+ DEBUGP(DIUCS, "Allocating IuCS subscriber conn: link_id %p, conn_id %" PRIx32 "\n",
+ ue->link, ue->conn_id);
conn = talloc_zero(network, struct gsm_subscriber_connection);
if (!conn)
return NULL;
conn->via_iface = IFACE_IUCS;
- conn->iu.link_id = link_id;
- conn->iu.conn_id = conn_id;
+ conn->iu.ue_ctx = ue;
llist_add_tail(&conn->entry, &network->subscr_conns);
return conn;
}
+static int same_ue_conn(struct ue_conn_ctx *a, struct ue_conn_ctx *b)
+{
+ if (a == b)
+ return 1;
+ return (a->link == b->link)
+ && (a->conn_id != b->conn_id);
+}
+
/* Return an existing IuCS subscriber connection record for the given link and
* connection IDs, or return NULL if not found. */
static struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
- uint8_t link_id,
- uint32_t conn_id)
+ struct ue_conn_ctx *ue)
{
struct gsm_subscriber_connection *conn;
+
llist_for_each_entry(conn, &network->subscr_conns, entry) {
if (conn->via_iface != IFACE_IUCS)
continue;
- if (conn->iu.link_id != link_id)
- continue;
- if (conn->iu.conn_id != conn_id)
+ if (!same_ue_conn(conn->iu.ue_ctx, ue))
continue;
- DEBUGP(DIUCS, "Found IuCS subscriber for link_id %" PRIx8 ", conn_id %" PRIx32 "\n",
- link_id, conn_id);
+ DEBUGP(DIUCS, "Found IuCS subscriber for link_id %p, conn_id %" PRIx32 "\n",
+ ue->link, ue->conn_id);
return conn;
}
- DEBUGP(DIUCS, "No IuCS subscriber found for link_id %" PRIx8 ", conn_id %" PRIx32 "\n",
- link_id, conn_id);
+ DEBUGP(DIUCS, "No IuCS subscriber found for link_id %p, conn_id %" PRIx32 "\n",
+ ue->link, ue->conn_id);
return NULL;
}
@@ -60,7 +64,7 @@ static struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_networ
* peer that sent the msg.
*
* For A-interface see libbsc/bsc_api.c gsm0408_rcvmsg(). */
-int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, uint8_t link_id)
+int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg)
{
int rc;
struct ue_conn_ctx *ue_ctx;
@@ -70,7 +74,7 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, uint8_t l
/* TODO: are there message types that could allow us to skip this
* search? */
- conn = subscr_conn_lookup_iu(network, link_id, ue_ctx->conn_id);
+ conn = subscr_conn_lookup_iu(network, ue_ctx);
if (conn) {
/* if we already have a connection, handle DTAP.
@@ -87,7 +91,7 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg, uint8_t l
} else {
/* allocate a new connection */
- conn = subscr_conn_allocate_iu(network, link_id, ue_ctx->conn_id);
+ conn = subscr_conn_allocate_iu(network, ue_ctx);
if (!conn)
abort();