diff options
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(); |