aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
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
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')
-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();