aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-05-08 15:12:20 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-08-11 18:34:01 +0200
commit89fecbff83ae5eeeac89ef15ab8781b65bd5d621 (patch)
tree9c504186fedfe8e576732fac23726d0c8cd0bf3a
parent0a65cc3e7bc2e5bd608ddd01d031beea4d33ad0e (diff)
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of adding the A-interface. Don't set msg->lchan nor msg->dst. Don't use lchan in libmsc. Decouple lac from bts. Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication: Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to different interfaces depending on the actual subscriber connection. While iu_tx() is going to be functional fairly soon, the a_tx() is going to be just a dummy for some time (see comment). Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer and an indicator for the Integrity Protection status on Iu (to be fully implemented in later commits). Add lac member to gsm_subscriber_connection, to allow decoupling from bts->location_area_code. The conn->lac will actually be set in iu.c in an upcoming commit ("add iucs.[hc]"). move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi(). libmsc: duplicate gsm0808 / gsm48 functions (towards BSC). In osmo-nitb, libmsc would directly call the functions on the BSC level, not always via the bsc_api. When separating libmsc from libbsc, some functions are missing from the linkage. Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also add a _tx to gsm0808_cipher_mode(): * add msc_gsm0808_tx_cipher_mode() (dummy/stub) * add msc_gsm48_tx_mm_serv_ack() * add msc_gsm48_tx_mm_serv_rej() Call these from libmsc instead of * gsm0808_cipher_mode() * gsm48_tx_mm_serv_ack() * gsm48_tx_mm_serv_rej() Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places. Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC, this will be done with an external MGCP gateway. Remove LCHAN_MODIFY from internal MNCC state machine. Temporarily disable all paging to be able to link libmsc without libbsc. Skip the paging part of channel_test because the paging is now disabled. Employ fake paging shims in order for msc_vlr_tests to still work. msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values for return val, to avoid dependency on libbsc headers. Make callable from other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c add gsm_encr to subscr_conn move subscr_request to gsm_subscriber.h subscr_request_channel() -> subscr_request_conn() move to libmsc: osmo_stats_vty_add_cmds() gsm_04_08: remove apply_codec_restrictions() gsm0408_test: use NULL for root ctx move to libbsc: gsm_bts_neighbor() move to libbsc: lchan_next_meas_rep() move vty config for t3212 to network level (periodic lu) remove unneccessary linking from some tests remove handle_abisip_signal() abis_rsl.c: don't use libvlr from libbsc gsm_subscriber_connection: put the LAC here, so that it is available without accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of transition: Iu and A will use this new field to pass the LAC around, but in a completely separate OsmoBSC this is not actually needed. It can be removed again from osmo-bsc.git when the time has come. Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall be added in osmo-bsc once the A-Interface code has settled. See OS#2389. Related: OS#1845 OS#2257 OS#2389 Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
-rw-r--r--include/openbsc/Makefile.am1
-rw-r--r--include/openbsc/gsm_04_08.h2
-rw-r--r--include/openbsc/gsm_data.h30
-rw-r--r--include/openbsc/gsm_subscriber.h28
-rw-r--r--include/openbsc/mncc.h4
-rw-r--r--include/openbsc/msc_ifaces.h47
-rw-r--r--include/openbsc/osmo_msc.h5
-rw-r--r--src/libbsc/abis_rsl.c13
-rw-r--r--src/libbsc/bsc_api.c1
-rw-r--r--src/libbsc/bsc_vty.c44
-rw-r--r--src/libbsc/gsm_04_08_utils.c55
-rw-r--r--src/libbsc/handover_decision.c21
-rw-r--r--src/libcommon-cs/common_cs.c27
-rw-r--r--src/libcommon-cs/common_cs_vty.c32
-rw-r--r--src/libcommon/gsm_data.c34
-rw-r--r--src/libcommon/talloc_ctx.c1
-rw-r--r--src/libmsc/Makefile.am2
-rw-r--r--src/libmsc/a_iface.c45
-rw-r--r--src/libmsc/gsm_04_08.c735
-rw-r--r--src/libmsc/gsm_04_11.c8
-rw-r--r--src/libmsc/gsm_subscriber.c68
-rw-r--r--src/libmsc/mncc_builtin.c49
-rw-r--r--src/libmsc/mncc_sock.c1
-rw-r--r--src/libmsc/msc_ifaces.c84
-rw-r--r--src/libmsc/osmo_msc.c22
-rw-r--r--src/libmsc/silent_call.c13
-rw-r--r--src/libmsc/smpp_openbsc.c6
-rw-r--r--src/libmsc/vty_interface_layer3.c57
-rw-r--r--tests/bsc/Makefile.am1
-rw-r--r--tests/channel/Makefile.am1
-rw-r--r--tests/db/Makefile.am2
-rw-r--r--tests/gsm0408/gsm0408_test.c4
-rw-r--r--tests/msc_vlr/Makefile.am4
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_authen.err16
-rw-r--r--tests/msc_vlr/msc_vlr_test_gsm_ciph.err10
-rw-r--r--tests/msc_vlr/msc_vlr_test_no_authen.err10
-rw-r--r--tests/msc_vlr/msc_vlr_test_reject_concurrency.err18
-rw-r--r--tests/msc_vlr/msc_vlr_test_umts_authen.err12
-rw-r--r--tests/msc_vlr/msc_vlr_tests.c30
39 files changed, 471 insertions, 1072 deletions
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 <osmocom/core/msgb.h>
+#include <openbsc/gsm_data.h>
+
+/* 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 <openbsc/handover.h>
#include <osmocom/gsm/gsm_utils.h>
+/* Get reference to a neighbor cell on a given BCCH ARFCN */
+static struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
+ uint16_t arfcn, uint8_t bsic)
+{
+ struct gsm_bts *neigh;
+ /* FIXME: use some better heuristics here to determine which cell
+ * using this ARFCN really is closest to the target cell. For
+ * now we simply assume that each ARFCN will only be used by one
+ * cell */
+
+ llist_for_each_entry(neigh, &bts->network->bts_list, list) {
+ /* FIXME: this is probably returning the same bts again!? */
+ if (neigh->c0->arfcn == arfcn &&
+ neigh->bsic == bsic)
+ return neigh;
+ }
+
+ return NULL;
+}
+
+
/* issue handover to a cell identified by ARFCN and BSIC */
static int handover_to_arfcn_bsic(struct gsm_lchan *lchan,
uint16_t arfcn, uint8_t bsic)
diff --git a/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 <info@sysmocom.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+
+#include <openbsc/debug.h>
+
+#include <openbsc/gsm_data.h>
+#include <openbsc/msc_ifaces.h>
+#include <openbsc/debug.h>
+
+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 <osmocom/abis/e1_input.h>
#include <osmocom/core/bitvec.h>
#include <openbsc/vlr.h>
+#include <openbsc/msc_ifaces.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0480.h>
@@ -71,11 +72,10 @@
#include <assert.h>
+
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)
+{
+ 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)
{
- 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);
}
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 <openbsc/chan_alloc.h>
#include <openbsc/vlr.h>
-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 <info@sysmocom.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/core/logging.h>
+
+#include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/msc_ifaces.h>
+
+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 <openbsc/osmo_msc.h>
#include <openbsc/bsc_api.h>
#include <openbsc/debug.h>
#include <openbsc/transaction.h>
@@ -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)
-{
- log("BTS/BSC sends out paging request to %s for channel type %d",
- bsc_subscr_name(sub), type);
+/* 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",
+ 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;
}