diff --git a/include/openbsc/Makefile.am b/include/openbsc/Makefile.am index 456a4a2d2..1dfe6c314 100644 --- a/include/openbsc/Makefile.am +++ b/include/openbsc/Makefile.am @@ -54,6 +54,7 @@ noinst_HEADERS = \ misdn.h \ mncc.h \ mncc_int.h \ + msc_ifaces.h \ nat_rewrite_trie.h \ network_listen.h \ oap_client.h \ diff --git a/include/openbsc/gsm_04_08.h b/include/openbsc/gsm_04_08.h index c40d96d65..6d6ead183 100644 --- a/include/openbsc/gsm_04_08.h +++ b/include/openbsc/gsm_04_08.h @@ -65,8 +65,6 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv, int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv); int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type); int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type); -int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, - struct msgb *msg, struct bsc_subscr *bsub); int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode); int gsm48_rx_rr_modif_ack(struct msgb *msg); diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h index fa2fed778..17b3d7172 100644 --- a/include/openbsc/gsm_data.h +++ b/include/openbsc/gsm_data.h @@ -26,6 +26,7 @@ struct gsm_subscriber_group; struct bsc_subscr; struct vlr_instance; struct vlr_subscr; +struct ue_conn_ctx; #define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3] @@ -117,6 +118,12 @@ struct gsm_classmark { uint8_t classmark3[14]; /* if cm3 gets extended by spec, it will be truncated */ }; +enum integrity_protection_state { + INTEGRITY_PROTECTION_NONE = 0, + INTEGRITY_PROTECTION_IK = 1, + INTEGRITY_PROTECTION_IK_CK = 2, +}; + /* active radio connection of a mobile subscriber */ struct gsm_subscriber_connection { /* global linked list of subscriber_connections */ @@ -176,6 +183,15 @@ struct gsm_subscriber_connection { enum ran_type via_ran; struct gsm_classmark classmark; + + uint16_t lac; + struct gsm_encr encr; + + /* which Iu-CS connection, if any. */ + struct { + struct ue_conn_ctx *ue_ctx; + int integrity_protection; + } iu; }; @@ -311,6 +327,12 @@ struct gsm_tz { }; struct gsm_network { + /* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for + * global settings and variables, "madly" mixing BSC and MSC stuff. Split + * this in e.g. struct osmo_bsc and struct osmo_msc, with the things + * these have in common, like country and network code, put in yet + * separate structs and placed as members in osmo_bsc and osmo_msc. */ + /* global parameters */ uint16_t country_code; uint16_t network_code; @@ -416,6 +438,9 @@ struct gsm_network { uint16_t gsup_server_port; struct vlr_instance *vlr; + + /* Periodic location update default value */ + uint8_t t3212; }; struct osmo_esme; @@ -471,10 +496,6 @@ extern void talloc_ctx_init(void *ctx_root); 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, @@ -557,7 +578,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/include/openbsc/gsm_subscriber.h b/include/openbsc/gsm_subscriber.h index c65b8a315..60eb0cd65 100644 --- a/include/openbsc/gsm_subscriber.h +++ b/include/openbsc/gsm_subscriber.h @@ -19,8 +19,6 @@ #define GSM_SUBSCRIBER_NO_EXPIRATION 0x0 -struct subscr_request; - enum gsm_subscriber_field { GSM_SUBSCRIBER_IMSI, GSM_SUBSCRIBER_TMSI, @@ -34,17 +32,35 @@ enum gsm_subscriber_update_reason { GSM_SUBSCRIBER_UPDATE_EQUIPMENT, }; -int subscr_update(struct vlr_subscr *vsub, struct gsm_bts *bts, int reason); +/* + * Struct for pending channel requests. This is managed in the + * llist_head requests of each subscriber. The reference counting + * should work in such a way that a subscriber with a pending request + * remains in memory. + */ +struct subscr_request { + struct llist_head entry; + + /* the callback data */ + gsm_cbfn *cbfn; + void *param; +}; + +int subscr_update(struct vlr_subscr *vsub, int reason); /* * Paging handling with authentication */ -struct subscr_request *subscr_request_channel(struct vlr_subscr *vsub, - int channel_type, - gsm_cbfn *cbfn, void *param); +struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub, + int channel_type, + gsm_cbfn *cbfn, void *param); + void subscr_remove_request(struct subscr_request *req); int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param); +int msc_fake_paging_request(struct vlr_subscr *vsub); +void msc_fake_paging_request_stop(struct vlr_subscr *vsub); + #endif /* _GSM_SUBSCR_H */ diff --git a/include/openbsc/mncc.h b/include/openbsc/mncc.h index 49f0c8b83..881e0418e 100644 --- a/include/openbsc/mncc.h +++ b/include/openbsc/mncc.h @@ -155,9 +155,6 @@ struct gsm_mncc { int notify; /* 0..127 */ int emergency; char imsi[16]; - - unsigned char lchan_type; - unsigned char lchan_mode; }; struct gsm_data_frame { @@ -179,7 +176,6 @@ struct gsm_mncc_hello { uint32_t called_offset; uint32_t signal_offset; uint32_t emergency_offset; - uint32_t lchan_type_offset; }; struct gsm_mncc_rtp { diff --git a/include/openbsc/msc_ifaces.h b/include/openbsc/msc_ifaces.h new file mode 100644 index 000000000..83aad92a4 --- /dev/null +++ b/include/openbsc/msc_ifaces.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC, + * i.e. in the direction towards the mobile device (MS aka UE). + * + * 2G will use the A-interface, + * 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS). + * + * To allow linking parts of the MSC code without having to include entire + * infrastructures of external libraries, the core transmitting and receiving + * functions are left unimplemented. For example, a unit test does not need to + * link against external ASN1 libraries if it is never going to encode actual + * outgoing messages. It is up to each building scope to implement real world + * functions or to plug mere dummy implementations. + * + * For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call + * either iu_tx() or a_tx() [note: at time of writing, the A-interface is not + * yet implemented]. When you try to link against libmsc, you will find that + * the compiler complains about an undefined reference to iu_tx(). If you, + * however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is + * available. A unit test may instead simply implement a dummy iu_tx() function + * and not link against osmo-iuh. + */ + +/* Each main linkage must implement this function (see comment above). */ +extern int iu_tx(struct msgb *msg, uint8_t sapi); + +/* So far this is a dummy implemented in libmsc/a_iface.c. When A-interface + * gets implemented, it should be in a separate lib (like libiu), this function + * should move there, and the following comment should remain here: " + * Each main linkage must implement this function (see comment above). + * " */ +extern int a_tx(struct msgb *msg); + +int msc_tx_dtap(struct gsm_subscriber_connection *conn, + struct msgb *msg); + +int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn); +int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value); + +/* TODO: specific to A interface, move this away */ +int msc_gsm0808_tx_cipher_mode(struct gsm_subscriber_connection *conn, int cipher, + const uint8_t *key, int len, int include_imeisv); diff --git a/include/openbsc/osmo_msc.h b/include/openbsc/osmo_msc.h index 0642c9109..5a26b6042 100644 --- a/include/openbsc/osmo_msc.h +++ b/include/openbsc/osmo_msc.h @@ -51,6 +51,11 @@ static inline const char *subscr_conn_from_name(enum subscr_conn_from val) return get_value_string(subscr_conn_from_names, val); } +enum msc_compl_l3_rc { + MSC_CONN_ACCEPT = 0, + MSC_CONN_REJECT = 1, +}; + struct bsc_api *msc_bsc_api(); diff --git a/src/libbsc/abis_rsl.c b/src/libbsc/abis_rsl.c index 7ae3eebd9..441b3861b 100644 --- a/src/libbsc/abis_rsl.c +++ b/src/libbsc/abis_rsl.c @@ -1423,6 +1423,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/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c index 947644eb3..c2828e3e8 100644 --- a/src/libbsc/bsc_api.c +++ b/src/libbsc/bsc_api.c @@ -264,6 +264,7 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha conn->lchan = lchan; conn->bts = lchan->ts->trx->bts; conn->via_ran = RAN_GERAN_A; + conn->lac = conn->bts->location_area_code; lchan->conn = conn; llist_add_tail(&conn->entry, &net->subscr_conns); return conn; diff --git a/src/libbsc/bsc_vty.c b/src/libbsc/bsc_vty.c index 3bd56eafb..722753ac1 100644 --- a/src/libbsc/bsc_vty.c +++ b/src/libbsc/bsc_vty.c @@ -593,18 +593,12 @@ 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); - if (gsm_bts_get_radio_link_timeout(bts) < 0) vty_out(vty, " radio-link-timeout infinite%s", VTY_NEWLINE); else vty_out(vty, " radio-link-timeout %d%s", gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE); + vty_out(vty, " channel allocator %s%s", bts->chan_alloc_reverse ? "descending" : "ascending", VTY_NEWLINE); @@ -841,6 +835,11 @@ static int config_write_net(struct vty *vty) 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; } @@ -2266,34 +2265,6 @@ 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, - "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; - - bts->si_common.chan_desc.t3212 = atoi(argv[0]) / 6; - - return CMD_SUCCESS; -} - -DEFUN(cfg_bts_no_per_loc_upd, cfg_bts_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; - - bts->si_common.chan_desc.t3212 = 0; - - return CMD_SUCCESS; -} - DEFUN(cfg_bts_radio_link_timeout, cfg_bts_radio_link_timeout_cmd, "radio-link-timeout <4-64>", "Radio link timeout criterion (BTS side)\n" @@ -4129,7 +4100,6 @@ int bsc_vty_init(struct gsm_network *network) install_element_ve(&show_paging_group_cmd); logging_vty_add_cmds(NULL); - osmo_stats_vty_add_cmds(); install_element(GSMNET_NODE, &cfg_net_neci_cmd); install_element(GSMNET_NODE, &cfg_net_handover_cmd); @@ -4189,8 +4159,6 @@ int bsc_vty_init(struct gsm_network *network) 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/src/libbsc/gsm_04_08_utils.c b/src/libbsc/gsm_04_08_utils.c index 3447d27cb..7c5e0e97a 100644 --- a/src/libbsc/gsm_04_08_utils.c +++ b/src/libbsc/gsm_04_08_utils.c @@ -270,61 +270,6 @@ int send_siemens_mrpci(struct gsm_lchan *lchan, return rsl_siemens_mrpci(lchan, &mrpci); } -int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type) -{ - /* Check the size for the classmark */ - if (length < 1 + *classmark2_lv) - return -1; - - uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; - if (length < 2 + *classmark2_lv + mi_lv[0]) - return -2; - - *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); -} - -int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, - char *mi_string, uint8_t *mi_type) -{ - static const uint32_t classmark_offset = - offsetof(struct gsm48_pag_resp, classmark2); - uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2; - return gsm48_extract_mi(classmark2_lv, length - classmark_offset, - mi_string, mi_type); -} - -int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, - struct msgb *msg, struct bsc_subscr *bsub) -{ - struct gsm_bts *bts = msg->lchan->ts->trx->bts; - struct gsm48_hdr *gh = msgb_l3(msg); - uint8_t *classmark2_lv = gh->data + 1; - - if (is_siemens_bts(bts)) - send_siemens_mrpci(msg->lchan, classmark2_lv); - - if (!conn->bsub) { - conn->bsub = bsub; - } else if (conn->bsub != bsub) { - LOGP(DRR, LOGL_ERROR, - "<- Channel already owned by someone else?\n"); - bsc_subscr_put(bsub); - return -EINVAL; - } else { - DEBUGP(DRR, "<- Channel already owned by us\n"); - bsc_subscr_put(bsub); - bsub = conn->bsub; - } - - rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_PAGING_COMPLETED]); - - /* Stop paging on the bts we received the paging response */ - paging_request_stop(&bts->network->bts_list, conn->bts, bsub, conn, - msg); - return 0; -} - /* Chapter 9.1.9: Ciphering Mode Command */ int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv) { diff --git a/src/libbsc/handover_decision.c b/src/libbsc/handover_decision.c index 0f07bcac6..8d7e047b7 100644 --- a/src/libbsc/handover_decision.c +++ b/src/libbsc/handover_decision.c @@ -33,6 +33,27 @@ #include #include +/* 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/src/libcommon-cs/common_cs.c b/src/libcommon-cs/common_cs.c index fc9caafa0..8e19bb2b8 100644 --- a/src/libcommon-cs/common_cs.c +++ b/src/libcommon-cs/common_cs.c @@ -56,6 +56,9 @@ struct gsm_network *gsm_network_init(void *ctx, net->country_code = country_code; net->network_code = network_code; + /* 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->subscr_conns); @@ -107,6 +110,30 @@ struct msgb *gsm48_create_loc_upd_rej(uint8_t cause) return msg; } +int gsm48_extract_mi(uint8_t *classmark2_lv, int length, char *mi_string, uint8_t *mi_type) +{ + /* Check the size for the classmark */ + if (length < 1 + *classmark2_lv) + return -1; + + uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1; + if (length < 2 + *classmark2_lv + mi_lv[0]) + return -2; + + *mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; + return gsm48_mi_to_string(mi_string, GSM48_MI_SIZE, mi_lv+1, *mi_lv); +} + +int gsm48_paging_extract_mi(struct gsm48_pag_resp *resp, int length, + char *mi_string, uint8_t *mi_type) +{ + static const uint32_t classmark_offset = + offsetof(struct gsm48_pag_resp, classmark2); + uint8_t *classmark2_lv = (uint8_t *) &resp->classmark2; + return gsm48_extract_mi(classmark2_lv, length - classmark_offset, + mi_string, mi_type); +} + uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref) { const uint8_t rp_msg_ref = *next_rp_ref; diff --git a/src/libcommon-cs/common_cs_vty.c b/src/libcommon-cs/common_cs_vty.c index 86b4c53e4..17916878b 100644 --- a/src/libcommon-cs/common_cs_vty.c +++ b/src/libcommon-cs/common_cs_vty.c @@ -284,6 +284,34 @@ DEFUN(cfg_net_no_timezone, return CMD_SUCCESS; } +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_network *net = vty->index; + + net->t3212 = atoi(argv[0]) / 6; + + return CMD_SUCCESS; +} + +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_network *net = vty->index; + + net->t3212 = 0; + + return CMD_SUCCESS; +} + static struct gsm_network *vty_global_gsm_network = NULL; /* initialize VTY elements used in both BSC and MSC */ @@ -293,6 +321,8 @@ int common_cs_vty_init(struct gsm_network *network, OSMO_ASSERT(vty_global_gsm_network == NULL); vty_global_gsm_network = network; + osmo_stats_vty_add_cmds(); + install_element(CONFIG_NODE, &cfg_net_cmd); install_node(&net_node, config_write_net); vty_install_default(GSMNET_NODE); @@ -310,6 +340,8 @@ int common_cs_vty_init(struct gsm_network *network, 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_net_dyn_ts_allow_tch_f_cmd); return CMD_SUCCESS; diff --git a/src/libcommon/gsm_data.c b/src/libcommon/gsm_data.c index 7c717a40f..f6fde37bd 100644 --- a/src/libcommon/gsm_data.c +++ b/src/libcommon/gsm_data.c @@ -71,25 +71,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_descs[_NUM_GSM_BTS_TYPE+1] = { { GSM_BTS_TYPE_UNKNOWN, "Unknown BTS Type" }, { GSM_BTS_TYPE_BS11, "Siemens BTS (BS-11 or compatible)" }, @@ -210,19 +191,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 *model, enum gsm_bts_features feat) { OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES); @@ -322,7 +290,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 */ gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */ llist_add_tail(&bts->list, &net->bts_list); diff --git a/src/libcommon/talloc_ctx.c b/src/libcommon/talloc_ctx.c index 5e3d9aebe..c8e9cd31d 100644 --- a/src/libcommon/talloc_ctx.c +++ b/src/libcommon/talloc_ctx.c @@ -44,7 +44,6 @@ void talloc_ctx_init(void *ctx_root) tall_authciphop_ctx = talloc_named_const(ctx_root, 0, "auth_ciph_oper"); tall_gsms_ctx = talloc_named_const(ctx_root, 0, "sms"); tall_subscr_ctx = talloc_named_const(ctx_root, 0, "subscriber"); - tall_sub_req_ctx = talloc_named_const(ctx_root, 0, "subscr_request"); tall_call_ctx = talloc_named_const(ctx_root, 0, "gsm_call"); tall_paging_ctx = talloc_named_const(ctx_root, 0, "paging_request"); tall_sigh_ctx = talloc_named_const(ctx_root, 0, "signal_handler"); diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am index bb2a4a186..3c0651456 100644 --- a/src/libmsc/Makefile.am +++ b/src/libmsc/Makefile.am @@ -23,6 +23,7 @@ noinst_LIBRARIES = \ $(NULL) libmsc_a_SOURCES = \ + a_iface.c \ auth.c \ db.c \ gsm_04_08.c \ @@ -32,6 +33,7 @@ libmsc_a_SOURCES = \ mncc.c \ mncc_builtin.c \ mncc_sock.c \ + msc_ifaces.c \ rrlp.c \ silent_call.c \ sms_queue.c \ diff --git a/src/libmsc/a_iface.c b/src/libmsc/a_iface.c new file mode 100644 index 000000000..1f471f97b --- /dev/null +++ b/src/libmsc/a_iface.c @@ -0,0 +1,45 @@ +/* A-interface implementation, from MSC to BSC */ + +/* (C) 2016 by sysmocom s.m.f.c GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include + +#include + +#include +#include +#include + +int a_tx(struct msgb *msg) +{ + LOGP(DMSC, LOGL_ERROR, "message to be sent to BSC, but A-interface" + " not implemented.\n%s\n", osmo_hexdump(msg->data, msg->len)); + return -1; +} + +int msc_gsm0808_tx_cipher_mode(struct gsm_subscriber_connection *conn, int cipher, + const uint8_t *key, int len, int include_imeisv) +{ + /* TODO generalize for A- and Iu interfaces, don't name after 08.08 */ + LOGP(DMSC, LOGL_ERROR, "gsm0808_cipher_mode(): message to be sent to" + " BSC, but A interface not yet implemented.\n"); + return -1; +} diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 6cea2420c..21ffaaad8 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -71,11 +72,10 @@ #include + 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, uint32_t send_tmsi); static int gsm48_tx_simple(struct gsm_subscriber_connection *conn, @@ -87,29 +87,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) @@ -126,27 +103,6 @@ static int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection * work that the caller no longer has to do */ if (trans) { gh->proto_discr = trans->protocol | (trans->transaction_id << 4); - msg->lchan = trans->conn->lchan; - } - - if (msg->lchan) { - struct e1inp_sign_link *sign_link = - msg->lchan->ts->trx->rsl_link; - - msg->dst = sign_link; - if (gsm48_hdr_pdisc(gh) == 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, msg->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, msg->lchan->ts->nr, - gh->proto_discr, gh->msg_type); } return gsm0808_submit_dtap(conn, msg, 0, 0); @@ -187,7 +143,6 @@ 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; msg = gsm48_create_loc_upd_rej(cause); @@ -196,11 +151,8 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause) return -1; } - msg->lchan = conn->lchan; - - LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT " - "LAC=%u BTS=%u\n", vlr_subscr_name(conn->vsub), - bts->location_area_code, bts->nr); + LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n", + vlr_subscr_name(conn->vsub)); return gsm48_conn_sendmsg(msg, conn, NULL); } @@ -214,8 +166,6 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, struct gsm48_loc_area_id *lai; uint8_t *mid; - msg->lchan = conn->lchan; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT; @@ -223,7 +173,7 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai)); gsm48_generate_lai(lai, conn->network->country_code, conn->network->network_code, - conn->bts->location_area_code); + conn->lac); if (send_tmsi == GSM_RESERVED_TMSI) { /* we did not allocate a TMSI to the MS, so we need to @@ -258,8 +208,6 @@ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ"); struct gsm48_hdr *gh; - msg->lchan = conn->lchan; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_ID_REQ; @@ -376,7 +324,7 @@ int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb *msg) &old_lai.plmn.mnc, &old_lai.lac); new_lai.plmn.mcc = conn->network->country_code; new_lai.plmn.mnc = conn->network->network_code; - new_lai.lac = conn->bts->location_area_code; + new_lai.lac = conn->lac; DEBUGP(DMM, "LU/new-LAC: %u/%u\n", old_lai.lac, new_lai.lac); lu_fsm = vlr_loc_update(conn->conn_fsm, @@ -437,8 +385,6 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn) int tzunits; int dst = 0; - msg->lchan = conn->lchan; - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_INFO; @@ -588,7 +534,6 @@ int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand, if (autn) DEBUGP(DMM, " AUTH REQ (autn = %s)\n", osmo_hexdump_nospc(autn, 16)); - msg->lchan = conn->lchan; gh->proto_discr = GSM48_PDISC_MM; gh->msg_type = GSM48_MT_MM_AUTH_REQ; @@ -663,7 +608,7 @@ accept_reuse: * b) Try to parse the TMSI. If we do not have one reject * c) Check that we know the subscriber with the TMSI otherwise reject * with a HLR cause - * d) Set the subscriber on the gsm_lchan and accept + * d) Set the subscriber on the conn and accept * * Keep this function non-static for direct invocation by unit tests. */ @@ -688,19 +633,19 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms lai.plmn.mcc = conn->network->country_code; lai.plmn.mnc = conn->network->network_code; - lai.lac = conn->bts->location_area_code; + lai.lac = conn->lac; DEBUGP(DMM, "<- CM SERVICE REQUEST "); if (msg->data_len < sizeof(struct gsm48_service_request*)) { DEBUGPC(DMM, "wrong sized message\n"); - return gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); + return msc_gsm48_tx_mm_serv_rej(conn, + GSM48_REJECT_INCORRECT_MESSAGE); } if (msg->data_len < req->mi_len + 6) { DEBUGPC(DMM, "does not fit in packet\n"); - return gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); + return msc_gsm48_tx_mm_serv_rej(conn, + GSM48_REJECT_INCORRECT_MESSAGE); } gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); @@ -716,8 +661,8 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms mi_string); } else { DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type); - return gsm48_tx_mm_serv_rej(conn, - GSM48_REJECT_INCORRECT_MESSAGE); + return msc_gsm48_tx_mm_serv_rej(conn, + GSM48_REJECT_INCORRECT_MESSAGE); } osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len)); @@ -740,9 +685,6 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms return rc; } - if (is_siemens_bts(conn->bts)) - send_siemens_mrpci(msg->lchan, classmark2-1); - vlr_proc_acc_req(conn->conn_fsm, SUBSCR_CONN_E_ACCEPTED, SUBSCR_CONN_E_CN_CLOSE, @@ -793,7 +735,6 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s break; } - /* TODO? We used to remember the subscriber's classmark1 here and * stored it in the old sqlite db, but now we store it in a conn that * will be discarded anyway: */ @@ -1100,7 +1041,7 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m lai.plmn.mcc = conn->network->country_code; lai.plmn.mnc = conn->network->network_code; - lai.lac = conn->bts->location_area_code; /* (will be replaced by conn->lac soon) */ + lai.lac = conn->lac; resp = (struct gsm48_pag_resp *) &gh->data[0]; gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh), @@ -1186,8 +1127,6 @@ int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF"); struct gsm48_hdr *gh; - msg->lchan = conn->lchan; - DEBUGP(DRR, "TX APPLICATION INFO id=0x%02x, len=%u\n", apdu_id, apdu_len); @@ -1279,8 +1218,6 @@ static int gsm48_tx_simple(struct gsm_subscriber_connection *conn, struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 TX SIMPLE"); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - msg->lchan = conn->lchan; - gh->proto_discr = pdisc; gh->msg_type = msg_type; @@ -1302,6 +1239,9 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans, struct msgb *msg; unsigned char *data; +#if BEFORE_MSCSPLIT + /* Re-enable this log output once we can obtain this information via + * A-interface, see OS#2391. */ if (trans) if (trans->conn && trans->conn->lchan) DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " @@ -1319,6 +1259,9 @@ 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)); +#else + DEBUGP(DCC, "Sending '%s' to MNCC.\n", get_mncc_name(msg_type)); +#endif mncc->msg_type = msg_type; @@ -1362,8 +1305,6 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) } if (trans->cc.state != GSM_CSTATE_NULL) new_cc_state(trans, GSM_CSTATE_NULL); - if (trans->conn) - trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref); } static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); @@ -1377,13 +1318,12 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, OSMO_ASSERT(!transt->conn); - /* check all tranactions (without lchan) for subscriber */ switch (event) { case GSM_PAGING_SUCCEEDED: DEBUGP(DCC, "Paging subscr %s succeeded!\n", vlr_subscr_msisdn_or_name(transt->vsub)); OSMO_ASSERT(conn); - /* Assign lchan */ + /* Assign conn */ transt->conn = conn; /* send SETUP request to called party */ gsm48_cc_tx_setup(transt, &transt->cc.msg); @@ -1410,235 +1350,6 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, return 0; } -static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable); - -/* handle audio path for handover */ -static int switch_for_handover(struct gsm_lchan *old_lchan, - struct gsm_lchan *new_lchan) -{ - struct rtp_socket *old_rs, *new_rs, *other_rs; - - /* Ask the new socket to send to the already known port. */ - if (new_lchan->conn->mncc_rtp_bridge) { - LOGP(DHO, LOGL_DEBUG, "Forwarding RTP\n"); - rsl_ipacc_mdcx(new_lchan, - old_lchan->abis_ip.connect_ip, - old_lchan->abis_ip.connect_port, 0); - return 0; - } - - if (ipacc_rtp_direct) { - LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n"); - return 0; - } - - /* RTP Proxy mode */ - new_rs = new_lchan->abis_ip.rtp_socket; - old_rs = old_lchan->abis_ip.rtp_socket; - - if (!new_rs) { - LOGP(DHO, LOGL_ERROR, "no RTP socket for new_lchan\n"); - return -EIO; - } - - rsl_ipacc_mdcx_to_rtpsock(new_lchan); - - if (!old_rs) { - LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n"); - return -EIO; - } - - /* copy rx_action and reference to other sock */ - new_rs->rx_action = old_rs->rx_action; - new_rs->tx_action = old_rs->tx_action; - new_rs->transmit = old_rs->transmit; - - switch (old_lchan->abis_ip.rtp_socket->rx_action) { - case RTP_PROXY: - other_rs = old_rs->proxy.other_sock; - rtp_socket_proxy(new_rs, other_rs); - /* delete reference to other end socket to prevent - * rtp_socket_free() from removing the inverse reference */ - old_rs->proxy.other_sock = NULL; - break; - case RTP_RECV_UPSTREAM: - new_rs->receive = old_rs->receive; - break; - case RTP_NONE: - break; - } - - return 0; -} - -static void maybe_switch_for_handover(struct gsm_lchan *lchan) -{ - struct gsm_lchan *old_lchan; - old_lchan = bsc_handover_pending(lchan); - if (old_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) -{ - struct gsm_bts *bts = lchan->ts->trx->bts; - struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts; - enum gsm_chan_t lt = lchan->type, rt = remote_lchan->type; - enum gsm48_chan_mode lm = lchan->tch_mode, rm = remote_lchan->tch_mode; - int rc; - - DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u,%s) and " - "(bts=%u,trx=%u,ts=%u,%s)\n", - bts->nr, lchan->ts->trx->nr, lchan->ts->nr, - get_value_string(gsm_chan_t_names, lt), - remote_bts->nr, remote_lchan->ts->trx->nr, remote_lchan->ts->nr, - get_value_string(gsm_chan_t_names, rt)); - - if (bts->type != remote_bts->type) { - LOGP(DCC, LOGL_ERROR, "Cannot switch calls between different BTS types yet\n"); - return -EINVAL; - } - - if (lt != rt) { - LOGP(DCC, LOGL_ERROR, "Cannot patch through call with different" - " channel types: local = %s, remote = %s\n", - get_value_string(gsm_chan_t_names, lt), - get_value_string(gsm_chan_t_names, rt)); - return -EBADSLT; - } - - if (lm != rm) { - LOGP(DCC, LOGL_ERROR, "Cannot patch through call with different" - " channel modes: local = %s, remote = %s\n", - get_value_string(gsm48_chan_mode_names, lm), - get_value_string(gsm48_chan_mode_names, rm)); - return -EMEDIUMTYPE; - } - - // todo: map between different bts types - switch (bts->type) { - case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMOBTS: - if (!ipacc_rtp_direct) { - if (!lchan->abis_ip.rtp_socket) { - LOGP(DHO, LOGL_ERROR, "no RTP socket for " - "lchan\n"); - return -EIO; - } - if (!remote_lchan->abis_ip.rtp_socket) { - LOGP(DHO, LOGL_ERROR, "no RTP socket for " - "remote_lchan\n"); - return -EIO; - } - - /* connect the TCH's to our RTP proxy */ - rc = rsl_ipacc_mdcx_to_rtpsock(lchan); - if (rc < 0) - return rc; - rc = rsl_ipacc_mdcx_to_rtpsock(remote_lchan); - if (rc < 0) - return rc; - /* connect them with each other */ - rtp_socket_proxy(lchan->abis_ip.rtp_socket, - remote_lchan->abis_ip.rtp_socket); - } else { - /* directly connect TCH RTP streams to each other */ - rc = rsl_ipacc_mdcx(lchan, remote_lchan->abis_ip.bound_ip, - remote_lchan->abis_ip.bound_port, - remote_lchan->abis_ip.rtp_payload2); - if (rc < 0) - return rc; - rc = rsl_ipacc_mdcx(remote_lchan, lchan->abis_ip.bound_ip, - lchan->abis_ip.bound_port, - lchan->abis_ip.rtp_payload2); - } - break; - case GSM_BTS_TYPE_BS11: - case GSM_BTS_TYPE_RBS2000: - case GSM_BTS_TYPE_NOKIA_SITE: - trau_mux_map_lchan(lchan, remote_lchan); - break; - default: - LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); - return -EINVAL; - } - - return 0; -} - /* bridge channels of two transactions */ static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge) { @@ -1654,81 +1365,8 @@ 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(LOG_CTX_VLR_SUBSCR, trans1->vsub); - /* through-connect channel */ - return tch_map(trans1->conn->lchan, trans2->conn->lchan); -} - -/* enable receive of channels to MNCC upqueue */ -static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable) -{ - struct gsm_trans *trans; - struct gsm_lchan *lchan; - struct gsm_bts *bts; - int rc; - - /* Find callref */ - trans = trans_find_by_callref(net, callref); - if (!trans) - return -EIO; - if (!trans->conn) - return 0; - - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - lchan = trans->conn->lchan; - bts = lchan->ts->trx->bts; - - /* store receive state */ - trans->tch_recv = enable; - - switch (bts->type) { - case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMOBTS: - if (ipacc_rtp_direct) { - LOGP(DCC, LOGL_ERROR, "Error: RTP proxy is disabled\n"); - return -EINVAL; - } - /* In case, we don't have a RTP socket to the BTS yet, the BTS - * will not be connected to our RTP proxy and the socket will - * not be assigned to the application interface. This method - * will be called again, once the audio socket is created and - * connected. */ - if (!lchan->abis_ip.rtp_socket) { - DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable); - return 0; - } - if (enable) { - /* connect the TCH's to our RTP proxy */ - rc = rsl_ipacc_mdcx_to_rtpsock(lchan); - if (rc < 0) - return rc; - /* assign socket to application interface */ - rtp_socket_upstream(lchan->abis_ip.rtp_socket, - net, callref); - } else - rtp_socket_upstream(lchan->abis_ip.rtp_socket, - net, 0); - break; - case GSM_BTS_TYPE_BS11: - case GSM_BTS_TYPE_RBS2000: - case GSM_BTS_TYPE_NOKIA_SITE: - /* In case we don't have a TCH with correct mode, the TRAU muxer - * will not be asigned to the application interface. This is - * performed by switch_trau_mux() after successful handover or - * assignment. */ - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - DEBUGP(DCC, "queue tch_recv_mncc request (%d)\n", enable); - return 0; - } - if (enable) - return trau_recv_lchan(lchan, callref); - return trau_mux_unmap(NULL, callref); - break; - default: - LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); - return -EINVAL; - } - - return 0; + /* future: msc_call_bridge(trans1, trans2); */ + return -1; } static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg) @@ -1868,7 +1506,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) memset(&setup, 0, sizeof(struct gsm_mncc)); setup.callref = trans->callref; - setup.lchan_type = trans->conn->lchan->type; + 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) @@ -1884,7 +1522,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)) { @@ -2024,7 +1661,7 @@ 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; - call_conf.lchan_type = trans->conn->lchan->type; + tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); #if 0 /* repeat */ @@ -2038,7 +1675,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)) { @@ -2728,7 +2364,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); @@ -2771,7 +2406,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); @@ -2812,7 +2446,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)) { @@ -2915,229 +2548,6 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) return mncc_recvmsg(trans->net, trans, MNCC_USERINFO_IND, &user); } -static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg) -{ - struct gsm_mncc *mode = arg; - struct gsm_lchan *lchan = trans->conn->lchan; - - /* - * We were forced to make an assignment a lot earlier and - * we should avoid sending another assignment that might - * even lead to a different kind of lchan (TCH/F vs. TCH/H). - * In case of rtp-bridge it is too late to change things - * here. - */ - if (trans->conn->mncc_rtp_bridge && lchan->tch_mode != GSM48_CMODE_SIGN) - return 0; - - return gsm0808_assign_req(trans->conn, mode->lchan_mode, - trans->conn->lchan->type != GSM_LCHAN_TCH_H); -} - -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) -{ - uint8_t data[sizeof(struct gsm_mncc)]; - struct gsm_mncc_rtp *rtp; - - memset(&data, 0, sizeof(data)); - rtp = (struct gsm_mncc_rtp *) &data[0]; - - rtp->callref = callref; - rtp->msg_type = cmd; - rtp->ip = addr; - rtp->port = port; - rtp->payload_type = payload_type; - rtp->payload_msg_type = payload_msg_type; - mncc_recvmsg(net, NULL, cmd, (struct gsm_mncc *)data); -} - -static void mncc_recv_rtp_sock(struct gsm_network *net, struct gsm_trans *trans, int cmd) -{ - struct gsm_lchan *lchan; - int msg_type; - - lchan = trans->conn->lchan; - switch (lchan->abis_ip.rtp_payload) { - case RTP_PT_GSM_FULL: - msg_type = GSM_TCHF_FRAME; - break; - case RTP_PT_GSM_EFR: - msg_type = GSM_TCHF_FRAME_EFR; - break; - case RTP_PT_GSM_HALF: - msg_type = GSM_TCHH_FRAME; - break; - case RTP_PT_AMR: - msg_type = GSM_TCH_FRAME_AMR; - break; - default: - LOGP(DMNCC, LOGL_ERROR, "%s unknown payload type %d\n", - gsm_lchan_name(lchan), lchan->abis_ip.rtp_payload); - msg_type = 0; - break; - } - - return mncc_recv_rtp(net, trans->callref, cmd, - lchan->abis_ip.bound_ip, - lchan->abis_ip.bound_port, - lchan->abis_ip.rtp_payload, - msg_type); -} - -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); -} - -static int tch_rtp_create(struct gsm_network *net, uint32_t callref) -{ - struct gsm_bts *bts; - struct gsm_lchan *lchan; - struct gsm_trans *trans; - enum gsm48_chan_mode m; - - /* Find callref */ - trans = trans_find_by_callref(net, callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "RTP create for non-existing trans\n"); - mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE); - return -EIO; - } - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - if (!trans->conn) { - LOGP(DMNCC, LOGL_NOTICE, "RTP create for trans without conn\n"); - mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE); - return 0; - } - - lchan = trans->conn->lchan; - bts = lchan->ts->trx->bts; - if (!is_ipaccess_bts(bts)) { - /* - * I want this to be straight forward and have no audio flow - * through the nitb/osmo-mss system. This currently means that - * this will not work with BS11/Nokia type BTS. We would need - * to have a trau<->rtp bridge for these but still preferable - * in another process. - */ - LOGP(DMNCC, LOGL_ERROR, "RTP create only works with IP systems\n"); - mncc_recv_rtp_err(net, callref, MNCC_RTP_CREATE); - return -EINVAL; - } - - trans->conn->mncc_rtp_bridge = 1; - /* - * *sigh* we need to pick a codec now. Pick the most generic one - * right now and hope we could fix that later on. This is very - * similiar to the routine above. - * Fallback to the internal MNCC mode to select a route. - */ - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - trans->conn->mncc_rtp_create_pending = 1; - m = mncc_codec_for_mode(lchan->type); - LOGP(DMNCC, LOGL_DEBUG, "RTP create: codec=%s, chan_type=%s\n", - get_value_string(gsm48_chan_mode_names, m), - get_value_string(gsm_chan_t_names, lchan->type)); - return gsm0808_assign_req(trans->conn, m, - lchan->type != GSM_LCHAN_TCH_H); - } - - mncc_recv_rtp_sock(trans->net, trans, MNCC_RTP_CREATE); - return 0; -} - -static int tch_rtp_connect(struct gsm_network *net, void *arg) -{ - struct gsm_lchan *lchan; - struct gsm_trans *trans; - struct gsm_mncc_rtp *rtp = arg; - - /* Find callref */ - trans = trans_find_by_callref(net, rtp->callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "RTP connect for non-existing trans\n"); - mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT); - return -EIO; - } - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - if (!trans->conn) { - LOGP(DMNCC, LOGL_ERROR, "RTP connect for trans without conn\n"); - mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT); - return 0; - } - - lchan = trans->conn->lchan; - LOGP(DMNCC, LOGL_DEBUG, "RTP connect: codec=%s, chan_type=%s\n", - get_value_string(gsm48_chan_mode_names, - mncc_codec_for_mode(lchan->type)), - get_value_string(gsm_chan_t_names, lchan->type)); - - /* TODO: Check if payload_msg_type is compatible with what we have */ - if (rtp->payload_type != lchan->abis_ip.rtp_payload) { - LOGP(DMNCC, LOGL_ERROR, "RTP connect with different RTP payload\n"); - mncc_recv_rtp_err(net, rtp->callref, MNCC_RTP_CONNECT); - } - - /* - * FIXME: payload2 can't be sent with MDCX as the osmo-bts code - * complains about both rtp and rtp payload2 being present in the - * same package! - */ - trans->conn->mncc_rtp_connect_pending = 1; - return rsl_ipacc_mdcx(lchan, rtp->ip, rtp->port, 0); -} - -static int tch_rtp_signal(struct gsm_lchan *lchan, int signal) -{ - struct gsm_network *net; - struct gsm_trans *tmp, *trans = NULL; - - net = lchan->ts->trx->bts->network; - llist_for_each_entry(tmp, &net->trans_list, entry) { - if (!tmp->conn) - continue; - if (tmp->conn->lchan != lchan && tmp->conn->ho_lchan != lchan) - continue; - trans = tmp; - break; - } - - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "%s IPA abis signal but no transaction.\n", - gsm_lchan_name(lchan)); - return 0; - } - - switch (signal) { - case S_ABISIP_CRCX_ACK: - if (lchan->conn->mncc_rtp_create_pending) { - lchan->conn->mncc_rtp_create_pending = 0; - LOGP(DMNCC, LOGL_NOTICE, "%s sending pending RTP create ind.\n", - gsm_lchan_name(lchan)); - mncc_recv_rtp_sock(net, trans, MNCC_RTP_CREATE); - } - /* - * TODO: this appears to be too early? Why not until after - * the handover detect or the handover complete? - */ - maybe_switch_for_handover(lchan); - break; - case S_ABISIP_MDCX_ACK: - if (lchan->conn->mncc_rtp_connect_pending) { - lchan->conn->mncc_rtp_connect_pending = 0; - LOGP(DMNCC, LOGL_NOTICE, "%s sending pending RTP connect ind.\n", - gsm_lchan_name(lchan)); - mncc_recv_rtp_sock(net, trans, MNCC_RTP_CONNECT); - } - break; - } - - return 0; -} - - static struct downstate { uint32_t states; int type; @@ -3191,9 +2601,6 @@ static struct downstate { MNCC_DISC_REQ, gsm48_cc_tx_disconnect}, {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ), /* 5.4.3.2 */ MNCC_REL_REQ, gsm48_cc_tx_release}, - /* special */ - {ALL_STATES, - MNCC_LCHAN_MODIFY, _gsm48_lchan_modify}, }; #define DOWNSLLEN \ @@ -3205,7 +2612,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)); @@ -3218,60 +2624,17 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) disconnect_bridge(net, arg, -rc); return rc; case MNCC_FRAME_DROP: - return tch_recv_mncc(net, data->callref, 0); case MNCC_FRAME_RECV: - return tch_recv_mncc(net, data->callref, 1); case MNCC_RTP_CREATE: - return tch_rtp_create(net, data->callref); case MNCC_RTP_CONNECT: - return tch_rtp_connect(net, arg); case MNCC_RTP_FREE: - /* unused right now */ - return -EIO; case GSM_TCHF_FRAME: case GSM_TCHF_FRAME_EFR: case GSM_TCHH_FRAME: case GSM_TCH_FRAME_AMR: - /* Find callref */ - trans = trans_find_by_callref(net, data->callref); - if (!trans) { - LOGP(DMNCC, LOGL_ERROR, "TCH frame for non-existing trans\n"); - return -EIO; - } - log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub); - if (!trans->conn) { - LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n"); - return 0; - } - if (!trans->conn->lchan) { - LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without lchan\n"); - return 0; - } - if (trans->conn->lchan->type != GSM_LCHAN_TCH_F - && trans->conn->lchan->type != GSM_LCHAN_TCH_H) { - /* This should be LOGL_ERROR or NOTICE, but - * unfortuantely it happens for a couple of frames at - * the beginning of every RTP connection */ - LOGP(DMNCC, LOGL_DEBUG, "TCH frame for lchan != TCH_F/TCH_H\n"); - return 0; - } - bts = trans->conn->lchan->ts->trx->bts; - switch (bts->type) { - case GSM_BTS_TYPE_NANOBTS: - case GSM_BTS_TYPE_OSMOBTS: - if (!trans->conn->lchan->abis_ip.rtp_socket) { - DEBUGP(DMNCC, "TCH frame to lchan without RTP connection\n"); - return 0; - } - return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, arg); - case GSM_BTS_TYPE_BS11: - case GSM_BTS_TYPE_RBS2000: - case GSM_BTS_TYPE_NOKIA_SITE: - return trau_send_frame(trans->conn->lchan, arg); - default: - LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type); - } - return -EINVAL; + LOGP(DMNCC, LOGL_ERROR, "RTP streams must be handled externally; %s not supported.\n", + get_mncc_name(msg_type)); + return -ENOTSUP; } memset(&rel, 0, sizeof(struct gsm_mncc)); @@ -3347,14 +2710,15 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) GSM48_CC_CAUSE_RESOURCE_UNAVAIL); return -ENOMEM; } - /* Find lchan */ + + /* Find conn */ conn = connection_for_subscr(vsub); - /* If subscriber has no lchan */ + /* If subscriber has no conn */ if (!conn) { /* find transaction with this subscriber already paging */ llist_for_each_entry(transt, &net->trans_list, entry) { - /* Transaction of our lchan? */ + /* Transaction of our conn? */ if (transt == trans || transt->vsub != vsub) continue; @@ -3372,7 +2736,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); /* Request a channel */ - trans->paging_request = subscr_request_channel( + trans->paging_request = subscr_request_conn( vsub, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, @@ -3386,7 +2750,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) vlr_subscr_put(vsub); return 0; } - /* Assign lchan */ + + /* Assign conn */ trans->conn = msc_subscr_conn_get(conn); vlr_subscr_put(vsub); } else { @@ -3399,7 +2764,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) /* if paging did not respond yet */ if (!conn) { - DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " + DEBUGP(DCC, "(sub %s) " "Received '%s' from MNCC in paging state\n", vlr_subscr_msisdn_or_name(trans->vsub), get_mncc_name(msg_type)); @@ -3414,9 +2779,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) return rc; } - DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) " + DEBUGP(DCC, "(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, trans->transaction_id, vlr_subscr_msisdn_or_name(trans->conn->vsub), get_mncc_name(msg_type), trans->cc.state, @@ -3513,12 +2877,16 @@ 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 + /* Re-enable this log output once we can obtain this information via + * A-interface, see OS#2391. */ 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, vlr_subscr_msisdn_or_name(conn->vsub), 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) { @@ -3836,11 +3204,18 @@ int msc_vlr_start(struct gsm_network *net) net->gsup_server_port); } -/* - * This will be run 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) +/* This is a temporary shim merely to ensure that the unit tests still work. It + * shall be removed as soon as Iu and A interface paging is implemented. */ +int msc_fake_paging_request(struct vlr_subscr *vsub) { - osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, NULL); + LOGP(DMM, LOGL_ERROR, "Paging currently not implemented in the MSC.\n"); + OSMO_ASSERT(false); +} + +/* This is a temporary shim merely to ensure that the unit tests still work. It + * shall be removed as soon as Iu and A interface paging is implemented. */ +void msc_fake_paging_request_stop(struct vlr_subscr *vsub) +{ + LOGP(DMM, LOGL_ERROR, "Paging currently not implemented in the MSC.\n"); + OSMO_ASSERT(false); } diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c index 6ad944b50..3255a3b6f 100644 --- a/src/libmsc/gsm_04_11.c +++ b/src/libmsc/gsm_04_11.c @@ -878,7 +878,7 @@ int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, } /* Take a SMS in gsm_sms structure and send it through an already - * existing lchan. We also assume that the caller ensured this lchan already + * existing conn. We also assume that the caller ensured this conn already * has a SAPI3 RLL connection! */ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms) { @@ -1004,7 +1004,7 @@ int gsm411_send_sms_subscr(struct vlr_subscr *vsub, struct gsm_subscriber_connection *conn; void *res; - /* check if we already have an open lchan to the subscriber. + /* check if we already have an open conn to the subscriber. * if yes, send the SMS this way */ conn = connection_for_subscr(vsub); if (conn) { @@ -1016,8 +1016,8 @@ int gsm411_send_sms_subscr(struct vlr_subscr *vsub, /* if not, we have to start paging */ LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n", vlr_subscr_name(vsub)); - res = subscr_request_channel(vsub, RSL_CHANNEED_SDCCH, - paging_cb_send_sms, sms); + res = subscr_request_conn(vsub, RSL_CHANNEED_SDCCH, paging_cb_send_sms, + sms); if (!res) { send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, GSM_PAGING_BUSY); sms_free(sms); diff --git a/src/libmsc/gsm_subscriber.c b/src/libmsc/gsm_subscriber.c index e9b2e0e5d..69d79b0c7 100644 --- a/src/libmsc/gsm_subscriber.c +++ b/src/libmsc/gsm_subscriber.c @@ -41,43 +41,6 @@ #include #include -void *tall_sub_req_ctx; - -int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, - gsm_cbfn *cb, void *cb_data); - - -/* - * Struct for pending channel requests. This is managed in the - * llist_head requests of each subscriber. The reference counting - * should work in such a way that a subscriber with a pending request - * remains in memory. - */ -struct subscr_request { - struct llist_head entry; - - /* the callback data */ - gsm_cbfn *cbfn; - void *param; -}; - -static struct bsc_subscr *vlr_subscr_to_bsc_sub(struct llist_head *bsc_subscribers, - struct vlr_subscr *vsub) -{ - struct bsc_subscr *sub; - /* TODO MSC split -- creating a BSC subscriber directly from MSC data - * structures in RAM. At some point the MSC will send a message to the - * BSC instead. */ - sub = bsc_subscr_find_or_create_by_imsi(bsc_subscribers, vsub->imsi); - sub->tmsi = vsub->tmsi; - sub->lac = vsub->lac; - return sub; -} - -/* - * We got the channel assigned and can now hand this channel - * over to one of our callbacks. - */ int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, struct msgb *msg, void *data, void *param) { @@ -85,22 +48,12 @@ int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, struct gsm_subscriber_connection *conn = data; struct vlr_subscr *vsub = param; struct paging_signal_data sig_data; - struct bsc_subscr *bsub; - struct gsm_network *net; OSMO_ASSERT(vsub && vsub->cs.is_paging); - net = vsub->vlr->user_ctx; - /* - * Stop paging on all other BTS. E.g. if this is - * the first timeout on a BTS then the others will - * timeout soon as well. Let's just stop everything - * and forget we wanted to page. - */ - - bsub = vlr_subscr_to_bsc_sub(conn->network->bsc_subscribers, vsub); - paging_request_stop(&net->bts_list, NULL, bsub, NULL, NULL); - bsc_subscr_put(bsub); + /* FIXME: implement stop paging in libmsc; + * faking it for the unit tests to still work */ + msc_fake_paging_request_stop(vsub); /* Inform parts of the system we don't know */ sig_data.vsub = vsub; @@ -126,22 +79,21 @@ int subscr_paging_dispatch(unsigned int hooknum, unsigned int event, return 0; } -struct subscr_request *subscr_request_channel(struct vlr_subscr *vsub, - int channel_type, - gsm_cbfn *cbfn, void *param) +struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub, int channel_type, gsm_cbfn *cbfn, + void *param) { int rc; struct subscr_request *request; - struct bsc_subscr *bsub; - struct gsm_network *net = vsub->vlr->user_ctx; /* Start paging.. we know it is async so we can do it before */ if (!vsub->cs.is_paging) { LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet.\n", vlr_subscr_name(vsub)); - bsub = vlr_subscr_to_bsc_sub(net->bsc_subscribers, vsub); - rc = paging_request(net, bsub, channel_type, NULL, NULL); - bsc_subscr_put(bsub); + + /* FIXME: implement paging in libmsc; + * faking it for the unit tests to still work */ + rc = msc_fake_paging_request(vsub); + if (rc <= 0) { LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n", vlr_subscr_name(vsub), rc); diff --git a/src/libmsc/mncc_builtin.c b/src/libmsc/mncc_builtin.c index 067cc92f8..ac6e7345d 100644 --- a/src/libmsc/mncc_builtin.c +++ b/src/libmsc/mncc_builtin.c @@ -65,21 +65,6 @@ static struct gsm_call *get_call_ref(uint32_t callref) return NULL; } -uint8_t mncc_codec_for_mode(int lchan_type) -{ - /* FIXME: check codec capabilities of the phone */ - - if (lchan_type != GSM_LCHAN_TCH_H) - return mncc_int.def_codec[0]; - else - return mncc_int.def_codec[1]; -} - -static uint8_t determine_lchan_mode(struct gsm_mncc *setup) -{ - return mncc_codec_for_mode(setup->lchan_type); -} - /* on incoming call, look up database and send setup to remote subscr. */ static int mncc_setup_ind(struct gsm_call *call, int msg_type, struct gsm_mncc *setup) @@ -137,9 +122,7 @@ static int mncc_setup_ind(struct gsm_call *call, int msg_type, /* modify mode */ memset(&mncc, 0, sizeof(struct gsm_mncc)); mncc.callref = call->callref; - mncc.lchan_mode = determine_lchan_mode(setup); - DEBUGP(DMNCC, "(call %x) Modify channel mode: %s\n", call->callref, - get_value_string(gsm48_chan_mode_names, mncc.lchan_mode)); + DEBUGP(DMNCC, "(call %x) Modify channel mode\n", call->callref); mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, &mncc); /* send setup to remote */ @@ -207,10 +190,6 @@ static int mncc_setup_cnf(struct gsm_call *call, int msg_type, bridge.callref[1] = call->remote_ref; DEBUGP(DMNCC, "(call %x) Bridging with remote.\n", call->callref); - /* in direct mode, we always have to bridge the channels */ - if (ipacc_rtp_direct) - return mncc_tx_to_cc(call->net, MNCC_BRIDGE, &bridge); - /* proxy mode */ if (!net->handover.active) { /* in the no-handover case, we can bridge, i.e. use @@ -279,28 +258,6 @@ static int mncc_rel_cnf(struct gsm_call *call, int msg_type, struct gsm_mncc *re return 0; } -/* receiving a (speech) traffic frame from the BSC code */ -static int mncc_rcv_data(struct gsm_call *call, int msg_type, - struct gsm_data_frame *dfr) -{ - struct gsm_trans *remote_trans; - - remote_trans = trans_find_by_callref(call->net, call->remote_ref); - - /* this shouldn't really happen */ - if (!remote_trans || !remote_trans->conn) { - LOGP(DMNCC, LOGL_ERROR, "No transaction or transaction without lchan?!?\n"); - return -EIO; - } - - /* 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); -} - - /* Internal MNCC handler input function (from CC -> MNCC -> here) */ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) { @@ -346,7 +303,8 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) } if (mncc_is_data_frame(msg_type)) { - rc = mncc_rcv_data(call, msg_type, arg); + LOGP(DMNCC, LOGL_ERROR, "(call %x) Received data frame, which is not supported.\n", + call->callref); goto out_free; } @@ -364,7 +322,6 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg) break; case MNCC_CALL_CONF_IND: /* we now need to MODIFY the channel */ - data->lchan_mode = determine_lchan_mode(data); mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, data); break; case MNCC_ALERT_IND: diff --git a/src/libmsc/mncc_sock.c b/src/libmsc/mncc_sock.c index 0efe3a156..0c696f2d9 100644 --- a/src/libmsc/mncc_sock.c +++ b/src/libmsc/mncc_sock.c @@ -224,7 +224,6 @@ static void queue_hello(struct mncc_sock_state *mncc) hello->called_offset = offsetof(struct gsm_mncc, called); hello->signal_offset = offsetof(struct gsm_mncc, signal); hello->emergency_offset = offsetof(struct gsm_mncc, emergency); - hello->lchan_type_offset = offsetof(struct gsm_mncc, lchan_type); msgb_enqueue(&mncc->net->upqueue, msg); mncc->conn_bfd.when |= BSC_FD_WRITE; diff --git a/src/libmsc/msc_ifaces.c b/src/libmsc/msc_ifaces.c new file mode 100644 index 000000000..001fcbac0 --- /dev/null +++ b/src/libmsc/msc_ifaces.c @@ -0,0 +1,84 @@ +/* Implementation for MSC decisions which interface to send messages out on. */ + +/* (C) 2016 by sysmocom s.m.f.c GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include + +static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg) +{ + switch (conn->via_ran) { + /* FUTURE + case RAN_GERAN_A: + msg->dst = conn; + return a_tx(msg); + + case RAN_UTRAN_IU: + msg->dst = conn->iu.ue_ctx; + return iu_tx(msg, 0); + */ + default: + LOGP(DMSC, LOGL_ERROR, + "msc_tx(): conn->via_ran invalid (%d)\n", + conn->via_ran); + return -1; + } +} + + +int msc_tx_dtap(struct gsm_subscriber_connection *conn, + struct msgb *msg) +{ + return msc_tx(conn, msg); +} + + +/* 9.2.5 CM service accept */ +int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACC"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + gh->proto_discr = GSM48_PDISC_MM; + gh->msg_type = GSM48_MT_MM_CM_SERV_ACC; + + DEBUGP(DMM, "-> CM SERVICE ACCEPT\n"); + + return msc_tx_dtap(conn, msg); +} + +/* 9.2.6 CM service reject */ +int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn, + enum gsm48_reject_value value) +{ + struct msgb *msg; + + msg = gsm48_create_mm_serv_rej(value); + if (!msg) { + LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n"); + return -1; + } + + DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value); + + return msc_tx_dtap(conn, msg); +} diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c index 95e58182c..c847b78f1 100644 --- a/src/libmsc/osmo_msc.c +++ b/src/libmsc/osmo_msc.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include @@ -69,9 +70,10 @@ static void subscr_conn_bump(struct gsm_subscriber_connection *conn) osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_BUMP, NULL); } -/* Receive a COMPLETE LAYER3 INFO from BSC */ -static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg, - uint16_t chosen_channel) +/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or + * MSC_CONN_REJECT */ +static int msc_compl_l3(struct gsm_subscriber_connection *conn, + struct msgb *msg, uint16_t chosen_channel) { /* Ownership of the gsm_subscriber_connection is still a bit mucky * between libbsc and libmsc. In libmsc, we use ref counting, but not @@ -87,7 +89,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg /* keep the use_count reserved, libbsc will discard. If we * released the ref count and discarded here, libbsc would * double-free. And we will not change bsc_api semantics. */ - return BSC_API_CONN_POL_REJECT; + return MSC_CONN_REJECT; } DEBUGP(DMM, "compl_l3: Keeping conn\n"); @@ -96,7 +98,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg /* If this should be kept, the conn->conn_fsm has placed a use_count */ msc_subscr_conn_put(conn); - return BSC_API_CONN_POL_ACCEPT; + return MSC_CONN_ACCEPT; #if 0 /* @@ -105,14 +107,14 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg * pending transaction or ongoing operation. */ if (conn->silent_call) - return BSC_API_CONN_POL_ACCEPT; - if (conn->sec_operation || conn->anch_operation) - return BSC_API_CONN_POL_ACCEPT; + return MSC_CONN_ACCEPT; + if (conn->loc_operation || conn->sec_operation || conn->anch_operation) + return MSC_CONN_ACCEPT; if (trans_has_conn(conn)) - return BSC_API_CONN_POL_ACCEPT; + return MSC_CONN_ACCEPT; LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n"); - return BSC_API_CONN_POL_REJECT; + return MSC_CONN_REJECT; #endif } diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c index 6f3fbf264..5fad4f491 100644 --- a/src/libmsc/silent_call.c +++ b/src/libmsc/silent_call.c @@ -52,8 +52,12 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event, switch (event) { case GSM_PAGING_SUCCEEDED: +#if BEFORE_MSCSPLIT + /* Re-enable this log output once we can obtain this information via + * A-interface, see OS#2391. */ DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n", conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn); +#endif conn->silent_call = 1; msc_subscr_conn_get(conn); /* increment lchan reference count */ @@ -126,7 +130,10 @@ int gsm_silent_call_start(struct vlr_subscr *vsub, void *data, int type) { struct subscr_request *req; - req = subscr_request_channel(vsub, type, paging_cb_silent, data); + /* FIXME the VTY command allows selecting a silent call channel type. + * This doesn't apply to the situation after MSCSPLIT with an + * A-interface. */ + req = subscr_request_conn(vsub, type, paging_cb_silent, data); return req != NULL; } @@ -143,8 +150,12 @@ int gsm_silent_call_stop(struct vlr_subscr *vsub) if (!conn->silent_call) return -EINVAL; +#if BEFORE_MSCSPLIT + /* Re-enable this log output once we can obtain this information via + * A-interface, see OS#2391. */ 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_subscr_conn_put(conn); diff --git a/src/libmsc/smpp_openbsc.c b/src/libmsc/smpp_openbsc.c index f06eb7d93..24a465373 100644 --- a/src/libmsc/smpp_openbsc.c +++ b/src/libmsc/smpp_openbsc.c @@ -423,6 +423,8 @@ void append_tlv_u16(tlv_t **req_tlv, uint16_t tag, uint16_t val) build_tlv(req_tlv, &tlv); } +#if BEFORE_MSCSPLIT +/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */ /* Append the Osmocom vendor-specific additional TLVs to a SMPP msg */ static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan) { @@ -461,6 +463,7 @@ static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan) (uint8_t *)vsub->imei, imei_len+1); } } +#endif struct { uint32_t smpp_status_code; @@ -680,8 +683,11 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, memcpy(deliver.short_message, sms->user_data, deliver.sm_length); } +#if BEFORE_MSCSPLIT + /* We currently have no lchan information. Re-add after A-interface, see OS#2390. */ if (esme->acl && esme->acl->osmocom_ext && conn->lchan) append_osmo_tlvs(&deliver.tlv, conn->lchan); +#endif ret = smpp_tx_deliver(esme, &deliver); if (ret < 0) diff --git a/src/libmsc/vty_interface_layer3.c b/src/libmsc/vty_interface_layer3.c index c393a8fa6..0106f91b3 100644 --- a/src/libmsc/vty_interface_layer3.c +++ b/src/libmsc/vty_interface_layer3.c @@ -553,57 +553,6 @@ DEFUN(ena_subscr_extension, return CMD_WARNING; } -DEFUN(ena_subscr_handover, - ena_subscr_handover_cmd, - "subscriber " SUBSCR_TYPES " ID handover BTS_NR", - SUBSCR_HELP "Handover the active connection\n" - "Number of the BTS to handover to\n") -{ - int ret; - struct gsm_subscriber_connection *conn; - struct gsm_bts *bts; - struct gsm_network *gsmnet = gsmnet_from_vty(vty); - struct vlr_subscr *vsub = - get_vsub_by_argv(gsmnet, argv[0], argv[1]); - - if (!vsub) { - vty_out(vty, "%% No subscriber found for %s %s.%s", - argv[0], argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - conn = connection_for_subscr(vsub); - if (!conn) { - vty_out(vty, "%% No active connection for subscriber %s %s.%s", - argv[0], argv[1], VTY_NEWLINE); - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - bts = gsm_bts_num(gsmnet, atoi(argv[2])); - if (!bts) { - vty_out(vty, "%% BTS with number(%d) could not be found.%s", - atoi(argv[2]), VTY_NEWLINE); - vlr_subscr_put(vsub); - return CMD_WARNING; - } - - /* now start the handover */ - ret = bsc_handover_start(conn->lchan, bts); - if (ret != 0) { - vty_out(vty, "%% Handover failed with errno %d.%s", - ret, VTY_NEWLINE); - } else { - vty_out(vty, "%% Handover started from %s", - gsm_lchan_name(conn->lchan)); - vty_out(vty, " to %s.%s", gsm_lchan_name(conn->ho_lchan), - VTY_NEWLINE); - } - - vlr_subscr_put(vsub); - return CMD_SUCCESS; -} - #define A3A8_ALG_TYPES "(none|xor|comp128v1)" #define A3A8_ALG_HELP \ "Use No A3A8 algorithm\n" \ @@ -652,9 +601,7 @@ static int scall_cbfn(unsigned int subsys, unsigned int signal, switch (signal) { case S_SCALL_SUCCESS: - vty_out(vty, "%% silent call on ARFCN %u timeslot %u%s", - sigdata->conn->lchan->ts->trx->arfcn, sigdata->conn->lchan->ts->nr, - VTY_NEWLINE); + vty_out(vty, "%% silent call success%s", VTY_NEWLINE); break; case S_SCALL_EXPIRED: vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE); @@ -670,7 +617,6 @@ DEFUN(show_stats, { struct gsm_network *net = gsmnet_from_vty(vty); - openbsc_vty_print_statistics(vty, net); vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s", net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current, net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current, @@ -1055,7 +1001,6 @@ int bsc_vty_init_extra(void) install_element(ENABLE_NODE, &ena_subscr_extension_cmd); install_element(ENABLE_NODE, &ena_subscr_authorized_cmd); install_element(ENABLE_NODE, &ena_subscr_a3a8_cmd); - install_element(ENABLE_NODE, &ena_subscr_handover_cmd); install_element(ENABLE_NODE, &subscriber_purge_cmd); install_element(ENABLE_NODE, &smsqueue_trigger_cmd); install_element(ENABLE_NODE, &smsqueue_max_cmd); diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am index 9de4145b7..904bdfcd7 100644 --- a/tests/bsc/Makefile.am +++ b/tests/bsc/Makefile.am @@ -32,7 +32,6 @@ bsc_test_SOURCES = \ bsc_test_LDADD = \ $(top_builddir)/src/libbsc/libbsc.a \ - $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ $(top_builddir)/src/libmgcp/libmgcp.a \ $(top_builddir)/src/libtrau/libtrau.a \ diff --git a/tests/channel/Makefile.am b/tests/channel/Makefile.am index c7164b475..dd78bdcf9 100644 --- a/tests/channel/Makefile.am +++ b/tests/channel/Makefile.am @@ -24,7 +24,6 @@ channel_test_SOURCES = \ $(NULL) channel_test_LDADD = \ - $(top_builddir)/src/libmsc/libmsc.a \ $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libvlr/libvlr.a \ $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ diff --git a/tests/db/Makefile.am b/tests/db/Makefile.am index 0eed5cd55..df421d86c 100644 --- a/tests/db/Makefile.am +++ b/tests/db/Makefile.am @@ -32,9 +32,7 @@ db_test_SOURCES = \ $(NULL) db_test_LDADD = \ - $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ - $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libcommon-cs/libcommon-cs.a \ $(top_builddir)/src/libtrau/libtrau.a \ $(top_builddir)/src/libcommon/libcommon.a \ diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c index 5a8c6ca52..1b326ee54 100644 --- a/tests/gsm0408/gsm0408_test.c +++ b/tests/gsm0408/gsm0408_test.c @@ -182,7 +182,7 @@ static inline void test_si2q_mu(void) static inline void test_si2q_u(void) { struct gsm_bts *bts; - struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL); + struct gsm_network *network = bsc_network_init(NULL, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater UARFCN generation:\n"); if (!network) @@ -210,7 +210,7 @@ static inline void test_si2q_u(void) static inline void test_si2q_e(void) { struct gsm_bts *bts; - struct gsm_network *network = bsc_network_init(tall_bsc_ctx, 1, 1, NULL); + struct gsm_network *network = bsc_network_init(NULL, 1, 1, NULL); printf("Testing SYSINFO_TYPE_2quater EARFCN generation:\n"); if (!network) diff --git a/tests/msc_vlr/Makefile.am b/tests/msc_vlr/Makefile.am index ebbfb5ca5..71450afdc 100644 --- a/tests/msc_vlr/Makefile.am +++ b/tests/msc_vlr/Makefile.am @@ -60,8 +60,8 @@ COMMON_LDFLAGS = \ -Wl,--wrap=gsup_client_create \ -Wl,--wrap=gsup_client_send \ -Wl,--wrap=gsm0808_submit_dtap \ - -Wl,--wrap=paging_request \ - -Wl,--wrap=paging_request_stop \ + -Wl,--wrap=msc_fake_paging_request \ + -Wl,--wrap=msc_fake_paging_request_stop \ -Wl,--wrap=gsm340_gen_scts \ -Wl,--wrap=RAND_bytes \ $(NULL) diff --git a/tests/msc_vlr/msc_vlr_test_gsm_authen.err b/tests/msc_vlr/msc_vlr_test_gsm_authen.err index 09ff4aea6..4ae4968e6 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_authen.err +++ b/tests/msc_vlr/msc_vlr_test_gsm_authen.err @@ -270,9 +270,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -351,7 +350,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 5 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -734,9 +732,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 + BTS/BSC sends out paging request to MSISDN:46071 paging_expecting_tmsi == 0x03020100 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -815,7 +812,6 @@ DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 5 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -1762,9 +1758,8 @@ DREF VLR subscr MSISDN:42342 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 3 DMM Subscriber MSISDN:42342 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000010650 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:42342 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:42342 usage decreases to: 3 @@ -1843,7 +1838,6 @@ DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 DREF VLR subscr MSISDN:42342 usage increases to: 5 DREF MSISDN:42342: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 diff --git a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err index f43d6f15c..1a9c39f75 100644 --- a/tests/msc_vlr/msc_vlr_test_gsm_ciph.err +++ b/tests/msc_vlr/msc_vlr_test_gsm_ciph.err @@ -287,9 +287,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -387,7 +386,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 5 DREF MSISDN:46071: MSC conn use + 1 == 2 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -786,9 +784,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 + BTS/BSC sends out paging request to MSISDN:46071 paging_expecting_tmsi == 0x03020100 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -886,7 +883,6 @@ DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 5 DREF MSISDN:46071: MSC conn use + 1 == 2 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 diff --git a/tests/msc_vlr/msc_vlr_test_no_authen.err b/tests/msc_vlr/msc_vlr_test_no_authen.err index 651ac2909..ec1c4e2a2 100644 --- a/tests/msc_vlr/msc_vlr_test_no_authen.err +++ b/tests/msc_vlr/msc_vlr_test_no_authen.err @@ -186,9 +186,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -227,7 +226,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 6 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -528,9 +526,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 + BTS/BSC sends out paging request to MSISDN:46071 paging_expecting_tmsi == 0x03020100 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -569,7 +566,6 @@ DVLR Process_Access_Request_VLR(50462976){PR_ARQ_S_DONE}: Process Access Request DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(50462976){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 6 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 diff --git a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err index c51d08af5..bebb16b2c 100644 --- a/tests/msc_vlr/msc_vlr_test_reject_concurrency.err +++ b/tests/msc_vlr/msc_vlr_test_reject_concurrency.err @@ -1188,9 +1188,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -1225,7 +1224,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 6 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -1403,9 +1401,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -1440,7 +1437,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 6 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -1635,9 +1631,8 @@ DREF VLR subscr MSISDN:46071 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 3 DMM Subscriber MSISDN:46071 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000004620 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:46071 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:46071 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:46071 usage decreases to: 3 @@ -1672,7 +1667,6 @@ DVLR Process_Access_Request_VLR(901700000004620){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000004620 usage decreases to: 0 DREF VLR subscr MSISDN:46071 usage increases to: 6 DREF MSISDN:46071: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005806470f1000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 diff --git a/tests/msc_vlr/msc_vlr_test_umts_authen.err b/tests/msc_vlr/msc_vlr_test_umts_authen.err index bfb4a8eda..744004ac5 100644 --- a/tests/msc_vlr/msc_vlr_test_umts_authen.err +++ b/tests/msc_vlr/msc_vlr_test_umts_authen.err @@ -253,9 +253,8 @@ DREF VLR subscr MSISDN:42342 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 3 DMM Subscriber MSISDN:42342 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000010650 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:42342 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:42342 usage decreases to: 3 @@ -335,7 +334,6 @@ DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 DREF VLR subscr MSISDN:42342 usage increases to: 5 DREF MSISDN:42342: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 @@ -665,9 +663,8 @@ DREF VLR subscr MSISDN:42342 usage increases to: 2 llist_count(&vsub->cs.requests) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 3 DMM Subscriber MSISDN:42342 not paged yet. - BTS/BSC sends out paging request to IMSI:901700000010650 for channel type 1 - strcmp(paging_expecting_imsi, sub->imsi) == 0 -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 + BTS/BSC sends out paging request to MSISDN:42342 + strcmp(paging_expecting_imsi, vsub->imsi) == 0 DREF VLR subscr MSISDN:42342 usage increases to: 4 llist_count(&vsub->cs.requests) == 1 DREF VLR subscr MSISDN:42342 usage decreases to: 3 @@ -747,7 +744,6 @@ DVLR Process_Access_Request_VLR(901700000010650){PR_ARQ_S_DONE}: Process Access DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_ACCEPTED DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: SUBSCR_CONN_FROM_PAGING_RESP DVLR Subscr_Conn(901700000010650){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_ACCEPTED -DREF BSC subscr IMSI:901700000010650 usage decreases to: 0 DREF VLR subscr MSISDN:42342 usage increases to: 5 DREF MSISDN:42342: MSC conn use + 1 == 3 - DTAP --> MS: 09015801000791447758100650004c0005802443f2000007101000000000445079da1e1ee7416937485e9ea7c965373d1d6683c270383b3d0ed3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb0c7ac3e9e9b7db05 diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c index a878be784..a40f1e5c6 100644 --- a/tests/msc_vlr/msc_vlr_tests.c +++ b/tests/msc_vlr/msc_vlr_tests.c @@ -252,33 +252,25 @@ void paging_expect_tmsi(uint32_t tmsi) paging_expecting_imsi = NULL; } -/* override, requires '-Wl,--wrap=paging_request' */ -int __real_paging_request(struct gsm_network *network, struct bsc_subscr *sub, - int type, gsm_cbfn *cbfn, void *data); -int __wrap_paging_request(struct gsm_network *network, struct bsc_subscr *sub, - int type, gsm_cbfn *cbfn, void *data) +/* override, requires '-Wl,--wrap=msc_fake_paging_request' */ +int __real_msc_fake_paging_request(struct vlr_subscr *vsub); +int __wrap_msc_fake_paging_request(struct vlr_subscr *vsub) { - log("BTS/BSC sends out paging request to %s for channel type %d", - bsc_subscr_name(sub), type); + log("BTS/BSC sends out paging request to %s", + vlr_subscr_name(vsub)); OSMO_ASSERT(paging_expecting_imsi || (paging_expecting_tmsi != GSM_RESERVED_TMSI)); if (paging_expecting_imsi) - VERBOSE_ASSERT(strcmp(paging_expecting_imsi, sub->imsi), == 0, "%d"); + VERBOSE_ASSERT(strcmp(paging_expecting_imsi, vsub->imsi), == 0, "%d"); if (paging_expecting_tmsi != GSM_RESERVED_TMSI) - VERBOSE_ASSERT(paging_expecting_tmsi, == sub->tmsi, "0x%08x"); + VERBOSE_ASSERT(paging_expecting_tmsi, == vsub->tmsi, "0x%08x"); paging_sent = true; paging_stopped = false; return 1; } -/* override, requires '-Wl,--wrap=paging_request_stop' */ -void __real_paging_request_stop(struct gsm_bts *_bts, - struct vlr_subscr *vsub, - struct gsm_subscriber_connection *conn, - struct msgb *msg); -void __wrap_paging_request_stop(struct gsm_bts *_bts, - struct vlr_subscr *vsub, - struct gsm_subscriber_connection *conn, - struct msgb *msg) +/* override, requires '-Wl,--wrap=msc_fake_paging_request_stop' */ +void __real_msc_fake_paging_request_stop(struct vlr_subscr *vsub); +void __wrap_msc_fake_paging_request_stop(struct vlr_subscr *vsub) { paging_stopped = true; }